public inbox for linux-rockchip@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup
@ 2026-04-03 18:52 Jonas Karlman
  2026-04-03 18:52 ` [PATCH v3 01/13] drm: bridge: dw_hdmi: Disable scrambler feature when not supported Jonas Karlman
                   ` (14 more replies)
  0 siblings, 15 replies; 24+ messages in thread
From: Jonas Karlman @ 2026-04-03 18:52 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss
  Cc: Laurent Pinchart, Jernej Skrabec, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
	Christian Hewitt, Diederik de Haas, dri-devel, linux-rockchip,
	linux-kernel, Jonas Karlman

This is a revival of an old dw-hdmi series and is the first series part
of a new effort to upstream old LibreELEC HDMI 2.0 patches for Rockchip
RK33xx devices.

This series ensure poweron/poweroff and CEC phys addr invalidation is
happening under drm mode_config mutex lock, and also ensure EDID is
updated after a HPD low voltage pulse by changing to debounce hotplug
processing.

These changes have mainly been tested on Rockchip RK3328, RK3399 and
RK3568 devices.

Rockchip uses the dw-hdmi connector, so this could use some more testing
with drivers that use the bridge connector.

Future planned series will likely convert dw-hdmi to a hdmi bridge and
add improved deep color support as preparation to add 10-bit and yuv420
output support on Rockchip RK33xx devices.

Testing with a Rock Pi 4 (RK3399) using a Reaspberry Pi Monitor with
Linux kms client console using drm.debug=0xe should log something like
following:

 Power cycle monitor using the power button:
  [CONNECTOR:68:HDMI-A-1] CEA VCDB 0x4a
  [CONNECTOR:68:HDMI-A-1] HDMI: DVI dual 0, max TMDS clock 0 kHz
  [CONNECTOR:68:HDMI-A-1] ELD monitor RPI MON156
  [CONNECTOR:68:HDMI-A-1] HDMI: latency present 0 0, video latency 0 0, audio latency 0 0
  [CONNECTOR:68:HDMI-A-1] ELD size 36, SAD count 1
  [CONNECTOR:68:HDMI-A-1] Same epoch counter 10
 
 Cable unplugged:
  [CONNECTOR:68:HDMI-A-1] EDID changed, epoch counter 11
  [CONNECTOR:68:HDMI-A-1] status updated from connected to disconnected
  [CONNECTOR:68:HDMI-A-1] Changed epoch counter 10 => 12
  [CONNECTOR:68:HDMI-A-1] generating connector hotplug event
  [CONNECTOR:68:HDMI-A-1] Sent hotplug event

 Cable connected:
  [CONNECTOR:68:HDMI-A-1] CEA VCDB 0x4a
  [CONNECTOR:68:HDMI-A-1] HDMI: DVI dual 0, max TMDS clock 0 kHz
  [CONNECTOR:68:HDMI-A-1] ELD monitor RPI MON156
  [CONNECTOR:68:HDMI-A-1] HDMI: latency present 0 0, video latency 0 0, audio latency 0 0
  [CONNECTOR:68:HDMI-A-1] ELD size 36, SAD count 1
  [CONNECTOR:68:HDMI-A-1] status updated from disconnected to connected
  [CONNECTOR:68:HDMI-A-1] Changed epoch counter 12 => 13
  [CONNECTOR:68:HDMI-A-1] generating connector hotplug event
  [CONNECTOR:68:HDMI-A-1] Sent hotplug event

Changes in v3:
- Rework EDID refresh handling to closer match bridge connector
- Use delayed work to debounce HPD processing
- Update commit messages
- Collect r-b tags
- Rebased on next-20260401
Link to v2: https://lore.kernel.org/r/20240908132823.3308029-1-jonas@kwiboo.se/

Changes in v2:
- Add patch to disable scrambler feature when not supported
- Add patch to only notify connected status on HPD interrupt
- Update commit messages
- Collect r-b tags
- Rebased on next-20240906
Link to v1: https://lore.kernel.org/r/20240611155108.1436502-1-jonas@kwiboo.se/

Jonas Karlman (13):
  drm: bridge: dw_hdmi: Disable scrambler feature when not supported
  drm: bridge: dw_hdmi: Only notify connected status on HPD interrupt
  drm: bridge: dw_hdmi: Call poweron/poweroff from atomic enable/disable
  drm: bridge: dw_hdmi: Use passed mode instead of stored previous_mode
  drm: bridge: dw_hdmi: Fold poweron and setup functions
  drm: bridge: dw_hdmi: Remove previous_mode and mode_set
  drm: bridge: dw_hdmi: Invalidate CEC phys addr from connector detect
  drm: bridge: dw_hdmi: Remove cec_notifier_mutex
  drm: bridge: dw_hdmi: Use delayed_work to debounce hotplug event
  drm: bridge: dw_hdmi: Use drm_connector_helper_hpd_irq_event()
  drm: bridge: dw_hdmi: Extract dw_hdmi_connector_status_update()
  drm: bridge: dw_hdmi: Use dw_hdmi_connector_status_update()
  drm: bridge: dw_hdmi: Use display_info is_hdmi and has_audio

 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 209 +++++++++-------------
 1 file changed, 80 insertions(+), 129 deletions(-)

-- 
2.53.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH v3 01/13] drm: bridge: dw_hdmi: Disable scrambler feature when not supported
  2026-04-03 18:52 [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup Jonas Karlman
@ 2026-04-03 18:52 ` Jonas Karlman
  2026-04-03 18:52 ` [PATCH v3 02/13] drm: bridge: dw_hdmi: Only notify connected status on HPD interrupt Jonas Karlman
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Jonas Karlman @ 2026-04-03 18:52 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: Christian Hewitt, Diederik de Haas, dri-devel, linux-rockchip,
	linux-kernel, Christopher Obbard

The scrambler feature can be left enabled when hotplugging from a sink
and mode that require scrambling to a sink that does not support SCDC or
scrambling.

Typically a blank screen or 'no signal' message can be observed after
using a HDMI 2.0 4K@60Hz mode and then hotplugging to a sink that only
support HDMI 1.4.

Fix this by disabling the scrambler feature when SCDC is not supported.

Fixes: 264fce6cc2c1 ("drm/bridge: dw-hdmi: Add SCDC and TMDS Scrambling support")
Reported-by: Christopher Obbard <chris.obbard@collabora.com>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
v3: Collect r-b tag
v2: New patch
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 0296e110ce65..9febcb58a1df 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2133,6 +2133,8 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
 				    HDMI_MC_SWRSTZ);
 			drm_scdc_set_scrambling(hdmi->curr_conn, 0);
 		}
+	} else if (hdmi->version >= 0x200a) {
+		hdmi_writeb(hdmi, 0, HDMI_FC_SCRAMBLER_CTRL);
 	}
 
 	/* Set up horizontal active pixel width */
-- 
2.53.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH v3 02/13] drm: bridge: dw_hdmi: Only notify connected status on HPD interrupt
  2026-04-03 18:52 [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup Jonas Karlman
  2026-04-03 18:52 ` [PATCH v3 01/13] drm: bridge: dw_hdmi: Disable scrambler feature when not supported Jonas Karlman
@ 2026-04-03 18:52 ` Jonas Karlman
  2026-04-27 18:04   ` Nicolas Frattaroli
  2026-04-03 18:52 ` [PATCH v3 03/13] drm: bridge: dw_hdmi: Call poweron/poweroff from atomic enable/disable Jonas Karlman
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 24+ messages in thread
From: Jonas Karlman @ 2026-04-03 18:52 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, Lucas Stach
  Cc: Christian Hewitt, Diederik de Haas, dri-devel, linux-rockchip,
	linux-kernel

drm_helper_hpd_irq_event() and drm_bridge_hpd_notify() may incorrectly
be called with a connected status when HPD is high and RX sense is
changed. This typically happens when the HDMI cable is unplugged,
shortly before the HPD is changed to low.

The original intent of commit da09daf88108 ("drm: bridge: dw_hdmi: only
trigger hotplug event on link change") was to signal hotplug event at
correct interrupt states.

Based on the commit message the intent was to trigger hotplug event:
- when HPD goes high (plugin)
- when both HPD and RX sense has gone low (plugout)

However, following interrupt state changes can typically be observed
when the HDMI cable is unplugged:
- RX interrupt:  HPD=high RX=low  -> triggers a connected event
- HPD interrupt: HPD=low  RX=low  -> triggers a disconnected event

Fix this by only notify connected status on the HPD interrupt when HPD
is going high, not on the RX sense interrupt when RX sense is changed.

After this a connected event should be triggered when HPD=high at HPD
interrupt, and a disconnected event should be triggered when both
HPD=low and RX=low at either HPD or RX interrupt.

Fixes: da09daf88108 ("drm: bridge: dw_hdmi: only trigger hotplug event on link change")
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
v3: Update commit message
v2: New patch
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 9febcb58a1df..3b851f12adfe 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -3140,7 +3140,8 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 			mutex_unlock(&hdmi->cec_notifier_mutex);
 		}
 
-		if (phy_stat & HDMI_PHY_HPD)
+		if ((intr_stat & HDMI_IH_PHY_STAT0_HPD) &&
+		    (phy_stat & HDMI_PHY_HPD))
 			status = connector_status_connected;
 
 		if (!(phy_stat & (HDMI_PHY_HPD | HDMI_PHY_RX_SENSE)))
-- 
2.53.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH v3 03/13] drm: bridge: dw_hdmi: Call poweron/poweroff from atomic enable/disable
  2026-04-03 18:52 [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup Jonas Karlman
  2026-04-03 18:52 ` [PATCH v3 01/13] drm: bridge: dw_hdmi: Disable scrambler feature when not supported Jonas Karlman
  2026-04-03 18:52 ` [PATCH v3 02/13] drm: bridge: dw_hdmi: Only notify connected status on HPD interrupt Jonas Karlman
@ 2026-04-03 18:52 ` Jonas Karlman
  2026-04-03 18:52 ` [PATCH v3 04/13] drm: bridge: dw_hdmi: Use passed mode instead of stored previous_mode Jonas Karlman
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Jonas Karlman @ 2026-04-03 18:52 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: Christian Hewitt, Diederik de Haas, dri-devel, linux-rockchip,
	linux-kernel

Change to only call poweron/poweroff from atomic_enable/atomic_disable
funcs instead of trying to be clever by keeping a bridge_is_on state and
poweron/off in the hotplug irq handler.

The bridge is already enabled/disabled depending on connection state
with the call to drm_helper_hpd_irq_event() in hotplug irq handler.

A benefit of this is that drm mode_config mutex is always held at
poweron/off, something that may reduce the need for the dw-hdmi mutex.

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
v3: Collect r-b tag
v2: Update commit message
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 33 ++---------------------
 1 file changed, 2 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 3b851f12adfe..eea266d01de3 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -169,7 +169,6 @@ struct dw_hdmi {
 	enum drm_connector_force force;	/* mutex-protected force state */
 	struct drm_connector *curr_conn;/* current connector (only valid when !disabled) */
 	bool disabled;			/* DRM has disabled our bridge */
-	bool bridge_is_on;		/* indicates the bridge is on */
 	bool rxsense;			/* rxsense state */
 	u8 phy_mask;			/* desired phy int mask settings */
 	u8 mc_clkdis;			/* clock disable register */
@@ -2398,8 +2397,6 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
 
 static void dw_hdmi_poweron(struct dw_hdmi *hdmi)
 {
-	hdmi->bridge_is_on = true;
-
 	/*
 	 * The curr_conn field is guaranteed to be valid here, as this function
 	 * is only be called when !hdmi->disabled.
@@ -2413,30 +2410,6 @@ static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
 		hdmi->phy.ops->disable(hdmi, hdmi->phy.data);
 		hdmi->phy.enabled = false;
 	}
-
-	hdmi->bridge_is_on = false;
-}
-
-static void dw_hdmi_update_power(struct dw_hdmi *hdmi)
-{
-	int force = hdmi->force;
-
-	if (hdmi->disabled) {
-		force = DRM_FORCE_OFF;
-	} else if (force == DRM_FORCE_UNSPECIFIED) {
-		if (hdmi->rxsense)
-			force = DRM_FORCE_ON;
-		else
-			force = DRM_FORCE_OFF;
-	}
-
-	if (force == DRM_FORCE_OFF) {
-		if (hdmi->bridge_is_on)
-			dw_hdmi_poweroff(hdmi);
-	} else {
-		if (!hdmi->bridge_is_on)
-			dw_hdmi_poweron(hdmi);
-	}
 }
 
 /*
@@ -2561,7 +2534,6 @@ static void dw_hdmi_connector_force(struct drm_connector *connector)
 
 	mutex_lock(&hdmi->mutex);
 	hdmi->force = connector->force;
-	dw_hdmi_update_power(hdmi);
 	dw_hdmi_update_phy_mask(hdmi);
 	mutex_unlock(&hdmi->mutex);
 }
@@ -2971,7 +2943,7 @@ static void dw_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
 	mutex_lock(&hdmi->mutex);
 	hdmi->disabled = true;
 	hdmi->curr_conn = NULL;
-	dw_hdmi_update_power(hdmi);
+	dw_hdmi_poweroff(hdmi);
 	dw_hdmi_update_phy_mask(hdmi);
 	handle_plugged_change(hdmi, false);
 	mutex_unlock(&hdmi->mutex);
@@ -2989,7 +2961,7 @@ static void dw_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
 	mutex_lock(&hdmi->mutex);
 	hdmi->disabled = false;
 	hdmi->curr_conn = connector;
-	dw_hdmi_update_power(hdmi);
+	dw_hdmi_poweron(hdmi);
 	dw_hdmi_update_phy_mask(hdmi);
 	handle_plugged_change(hdmi, true);
 	mutex_unlock(&hdmi->mutex);
@@ -3089,7 +3061,6 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)
 		if (hpd)
 			hdmi->rxsense = true;
 
-		dw_hdmi_update_power(hdmi);
 		dw_hdmi_update_phy_mask(hdmi);
 	}
 	mutex_unlock(&hdmi->mutex);
-- 
2.53.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH v3 04/13] drm: bridge: dw_hdmi: Use passed mode instead of stored previous_mode
  2026-04-03 18:52 [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup Jonas Karlman
                   ` (2 preceding siblings ...)
  2026-04-03 18:52 ` [PATCH v3 03/13] drm: bridge: dw_hdmi: Call poweron/poweroff from atomic enable/disable Jonas Karlman
@ 2026-04-03 18:52 ` Jonas Karlman
  2026-04-03 18:52 ` [PATCH v3 05/13] drm: bridge: dw_hdmi: Fold poweron and setup functions Jonas Karlman
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Jonas Karlman @ 2026-04-03 18:52 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: Christian Hewitt, Diederik de Haas, dri-devel, linux-rockchip,
	linux-kernel

Use the passed mode instead of mixing use of passed mode and the stored
previous_mode in dw_hdmi_setup(). The passed mode is currenly always the
previous_mode.

Also fix a small typo and add a variable to help shorten a code line.

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
v3: Collect r-b tag
v2: Update commit message, s/type/typo/
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index eea266d01de3..c03a86284a95 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2256,6 +2256,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi,
 			 const struct drm_connector *connector,
 			 const struct drm_display_mode *mode)
 {
+	const struct drm_display_info *display = &connector->display_info;
 	int ret;
 
 	hdmi_disable_overflow_interrupts(hdmi);
@@ -2301,12 +2302,10 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi,
 	hdmi->hdmi_data.video_mode.mdataenablepolarity = true;
 
 	/* HDMI Initialization Step B.1 */
-	hdmi_av_composer(hdmi, &connector->display_info, mode);
+	hdmi_av_composer(hdmi, display, mode);
 
-	/* HDMI Initializateion Step B.2 */
-	ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data,
-				  &connector->display_info,
-				  &hdmi->previous_mode);
+	/* HDMI Initialization Step B.2 */
+	ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, display, mode);
 	if (ret)
 		return ret;
 	hdmi->phy.enabled = true;
-- 
2.53.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH v3 05/13] drm: bridge: dw_hdmi: Fold poweron and setup functions
  2026-04-03 18:52 [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup Jonas Karlman
                   ` (3 preceding siblings ...)
  2026-04-03 18:52 ` [PATCH v3 04/13] drm: bridge: dw_hdmi: Use passed mode instead of stored previous_mode Jonas Karlman
@ 2026-04-03 18:52 ` Jonas Karlman
  2026-04-03 18:52 ` [PATCH v3 06/13] drm: bridge: dw_hdmi: Remove previous_mode and mode_set Jonas Karlman
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Jonas Karlman @ 2026-04-03 18:52 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: Christian Hewitt, Diederik de Haas, dri-devel, linux-rockchip,
	linux-kernel

Fold the poweron and setup functions into one function and use the
adjusted_mode directly from the new crtc_state to remove the need of
storing previous_mode.

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
v3: Collect r-b tag
v2: No change
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index c03a86284a95..7e7147b14614 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2252,9 +2252,9 @@ static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
 		    HDMI_IH_MUTE_FC_STAT2);
 }
 
-static int dw_hdmi_setup(struct dw_hdmi *hdmi,
-			 const struct drm_connector *connector,
-			 const struct drm_display_mode *mode)
+static int dw_hdmi_poweron(struct dw_hdmi *hdmi,
+			   const struct drm_connector *connector,
+			   const struct drm_display_mode *mode)
 {
 	const struct drm_display_info *display = &connector->display_info;
 	int ret;
@@ -2394,15 +2394,6 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
 	hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE);
 }
 
-static void dw_hdmi_poweron(struct dw_hdmi *hdmi)
-{
-	/*
-	 * The curr_conn field is guaranteed to be valid here, as this function
-	 * is only be called when !hdmi->disabled.
-	 */
-	dw_hdmi_setup(hdmi, hdmi->curr_conn, &hdmi->previous_mode);
-}
-
 static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
 {
 	if (hdmi->phy.enabled) {
@@ -2952,15 +2943,19 @@ static void dw_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
 					 struct drm_atomic_state *state)
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
+	const struct drm_display_mode *mode;
 	struct drm_connector *connector;
+	struct drm_crtc *crtc;
 
 	connector = drm_atomic_get_new_connector_for_encoder(state,
 							     bridge->encoder);
+	crtc = drm_atomic_get_new_connector_state(state, connector)->crtc;
+	mode = &drm_atomic_get_new_crtc_state(state, crtc)->adjusted_mode;
 
 	mutex_lock(&hdmi->mutex);
 	hdmi->disabled = false;
 	hdmi->curr_conn = connector;
-	dw_hdmi_poweron(hdmi);
+	dw_hdmi_poweron(hdmi, connector, mode);
 	dw_hdmi_update_phy_mask(hdmi);
 	handle_plugged_change(hdmi, true);
 	mutex_unlock(&hdmi->mutex);
-- 
2.53.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH v3 06/13] drm: bridge: dw_hdmi: Remove previous_mode and mode_set
  2026-04-03 18:52 [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup Jonas Karlman
                   ` (4 preceding siblings ...)
  2026-04-03 18:52 ` [PATCH v3 05/13] drm: bridge: dw_hdmi: Fold poweron and setup functions Jonas Karlman
@ 2026-04-03 18:52 ` Jonas Karlman
  2026-04-03 18:52 ` [PATCH v3 07/13] drm: bridge: dw_hdmi: Invalidate CEC phys addr from connector detect Jonas Karlman
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Jonas Karlman @ 2026-04-03 18:52 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: Christian Hewitt, Diederik de Haas, dri-devel, linux-rockchip,
	linux-kernel

With the use of adjusted_mode directly from the crtc_state there is no
longer a need to store a copy in previous_mode, remove it and the now
unneeded mode_set ops.

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
v3: Collect r-b tag
v2: No change
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 19 +------------------
 1 file changed, 1 insertion(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 7e7147b14614..aa4949de9173 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -154,8 +154,6 @@ struct dw_hdmi {
 		bool enabled;
 	} phy;
 
-	struct drm_display_mode previous_mode;
-
 	struct i2c_adapter *ddc;
 	void __iomem *regs;
 	bool sink_is_hdmi;
@@ -165,7 +163,7 @@ struct dw_hdmi {
 	struct pinctrl_state *default_state;
 	struct pinctrl_state *unwedge_state;
 
-	struct mutex mutex;		/* for state below and previous_mode */
+	struct mutex mutex;		/* for state below */
 	enum drm_connector_force force;	/* mutex-protected force state */
 	struct drm_connector *curr_conn;/* current connector (only valid when !disabled) */
 	bool disabled;			/* DRM has disabled our bridge */
@@ -2911,20 +2909,6 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
 	return mode_status;
 }
 
-static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
-				    const struct drm_display_mode *orig_mode,
-				    const struct drm_display_mode *mode)
-{
-	struct dw_hdmi *hdmi = bridge->driver_private;
-
-	mutex_lock(&hdmi->mutex);
-
-	/* Store the display mode for plugin/DKMS poweron events */
-	drm_mode_copy(&hdmi->previous_mode, mode);
-
-	mutex_unlock(&hdmi->mutex);
-}
-
 static void dw_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
 					  struct drm_atomic_state *state)
 {
@@ -2988,7 +2972,6 @@ static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
 	.atomic_get_input_bus_fmts = dw_hdmi_bridge_atomic_get_input_bus_fmts,
 	.atomic_enable = dw_hdmi_bridge_atomic_enable,
 	.atomic_disable = dw_hdmi_bridge_atomic_disable,
-	.mode_set = dw_hdmi_bridge_mode_set,
 	.mode_valid = dw_hdmi_bridge_mode_valid,
 	.detect = dw_hdmi_bridge_detect,
 	.edid_read = dw_hdmi_bridge_edid_read,
-- 
2.53.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH v3 07/13] drm: bridge: dw_hdmi: Invalidate CEC phys addr from connector detect
  2026-04-03 18:52 [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup Jonas Karlman
                   ` (5 preceding siblings ...)
  2026-04-03 18:52 ` [PATCH v3 06/13] drm: bridge: dw_hdmi: Remove previous_mode and mode_set Jonas Karlman
@ 2026-04-03 18:52 ` Jonas Karlman
  2026-04-03 18:52 ` [PATCH v3 08/13] drm: bridge: dw_hdmi: Remove cec_notifier_mutex Jonas Karlman
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Jonas Karlman @ 2026-04-03 18:52 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: Christian Hewitt, Diederik de Haas, dri-devel, linux-rockchip,
	linux-kernel

Wait until the connector detect ops is called to invalidate CEC phys
addr instead of doing it directly from the irq handler.

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
v3: No change
v2: Collect r-b tag
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index aa4949de9173..975edd6e695a 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2470,7 +2470,17 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 {
 	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
 					     connector);
-	return dw_hdmi_detect(hdmi);
+	enum drm_connector_status status;
+
+	status = dw_hdmi_detect(hdmi);
+
+	if (status == connector_status_disconnected) {
+		mutex_lock(&hdmi->cec_notifier_mutex);
+		cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
+		mutex_unlock(&hdmi->cec_notifier_mutex);
+	}
+
+	return status;
 }
 
 static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
@@ -3082,12 +3092,6 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 				       phy_stat & HDMI_PHY_HPD,
 				       phy_stat & HDMI_PHY_RX_SENSE);
 
-		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0) {
-			mutex_lock(&hdmi->cec_notifier_mutex);
-			cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
-			mutex_unlock(&hdmi->cec_notifier_mutex);
-		}
-
 		if ((intr_stat & HDMI_IH_PHY_STAT0_HPD) &&
 		    (phy_stat & HDMI_PHY_HPD))
 			status = connector_status_connected;
-- 
2.53.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH v3 08/13] drm: bridge: dw_hdmi: Remove cec_notifier_mutex
  2026-04-03 18:52 [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup Jonas Karlman
                   ` (6 preceding siblings ...)
  2026-04-03 18:52 ` [PATCH v3 07/13] drm: bridge: dw_hdmi: Invalidate CEC phys addr from connector detect Jonas Karlman
@ 2026-04-03 18:52 ` Jonas Karlman
  2026-04-03 18:52 ` [PATCH v3 09/13] drm: bridge: dw_hdmi: Use delayed_work to debounce hotplug event Jonas Karlman
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Jonas Karlman @ 2026-04-03 18:52 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: Christian Hewitt, Diederik de Haas, dri-devel, linux-rockchip,
	linux-kernel

With CEC phys addr invalidation moved away from the irq handler there is
no longer a need for cec_notifier_mutex, remove it.

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
v3: No change
v2: Collect r-b tag
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 975edd6e695a..f3f8144ae98e 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -187,7 +187,6 @@ struct dw_hdmi {
 	void (*enable_audio)(struct dw_hdmi *hdmi);
 	void (*disable_audio)(struct dw_hdmi *hdmi);
 
-	struct mutex cec_notifier_mutex;
 	struct cec_notifier *cec_notifier;
 
 	hdmi_codec_plugged_cb plugged_cb;
@@ -2474,11 +2473,8 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 
 	status = dw_hdmi_detect(hdmi);
 
-	if (status == connector_status_disconnected) {
-		mutex_lock(&hdmi->cec_notifier_mutex);
+	if (status == connector_status_disconnected)
 		cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
-		mutex_unlock(&hdmi->cec_notifier_mutex);
-	}
 
 	return status;
 }
@@ -2592,9 +2588,7 @@ static int dw_hdmi_connector_create(struct dw_hdmi *hdmi)
 	if (!notifier)
 		return -ENOMEM;
 
-	mutex_lock(&hdmi->cec_notifier_mutex);
 	hdmi->cec_notifier = notifier;
-	mutex_unlock(&hdmi->cec_notifier_mutex);
 
 	return 0;
 }
@@ -2893,10 +2887,8 @@ static void dw_hdmi_bridge_detach(struct drm_bridge *bridge)
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
 
-	mutex_lock(&hdmi->cec_notifier_mutex);
 	cec_notifier_conn_unregister(hdmi->cec_notifier);
 	hdmi->cec_notifier = NULL;
-	mutex_unlock(&hdmi->cec_notifier_mutex);
 }
 
 static enum drm_mode_status
@@ -3321,7 +3313,6 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
 
 	mutex_init(&hdmi->mutex);
 	mutex_init(&hdmi->audio_mutex);
-	mutex_init(&hdmi->cec_notifier_mutex);
 	spin_lock_init(&hdmi->audio_lock);
 
 	ret = dw_hdmi_parse_dt(hdmi);
-- 
2.53.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH v3 09/13] drm: bridge: dw_hdmi: Use delayed_work to debounce hotplug event
  2026-04-03 18:52 [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup Jonas Karlman
                   ` (7 preceding siblings ...)
  2026-04-03 18:52 ` [PATCH v3 08/13] drm: bridge: dw_hdmi: Remove cec_notifier_mutex Jonas Karlman
@ 2026-04-03 18:52 ` Jonas Karlman
  2026-04-27 18:27   ` Nicolas Frattaroli
  2026-04-28 12:38   ` Dmitry Baryshkov
  2026-04-03 18:52 ` [PATCH v3 10/13] drm: bridge: dw_hdmi: Use drm_connector_helper_hpd_irq_event() Jonas Karlman
                   ` (5 subsequent siblings)
  14 siblings, 2 replies; 24+ messages in thread
From: Jonas Karlman @ 2026-04-03 18:52 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: Christian Hewitt, Diederik de Haas, dri-devel, linux-rockchip,
	linux-kernel

HDMI Specification Version 1.4b chapter 8.5 mentions:

  An HDMI Sink shall not assert high voltage level on its Hot Plug
  Detect pin when the E-EDID is not available for reading.

  A Source may use a high voltage level Hot Plug Detect signal to
  initiate the reading of E-EDID data.

  An HDMI Sink shall indicate any change to the contents of the E-EDID
  by driving a low voltage level pulse on the Hot Plug Detect pin. This
  pulse shall be at least 100 msec.

Use a work queue to debounce reacting on HPD events to better handle a
HPD low voltage level pulse when a sink changes the EDID.

The 1100 msec hotplug debounce timeout was arbitrarily picked to match
other drivers using same const, and testing using a Raspberry Pi Monitor
seem to use a 200-300 msec pulse when going from standby to power on
state.

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
v3: New patch
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 24 +++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index f3f8144ae98e..4d079b689b3b 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -51,6 +51,8 @@
 
 #define HDMI14_MAX_TMDSCLK	340000000
 
+#define HOTPLUG_DEBOUNCE_MS	1100
+
 static const u16 csc_coeff_default[3][4] = {
 	{ 0x2000, 0x0000, 0x0000, 0x0000 },
 	{ 0x0000, 0x2000, 0x0000, 0x0000 },
@@ -192,6 +194,7 @@ struct dw_hdmi {
 	hdmi_codec_plugged_cb plugged_cb;
 	struct device *codec_dev;
 	enum drm_connector_status last_connector_result;
+	struct delayed_work hpd_work;
 };
 
 const struct dw_hdmi_plat_data *dw_hdmi_to_plat_data(struct dw_hdmi *hdmi)
@@ -2528,6 +2531,7 @@ static void dw_hdmi_connector_force(struct drm_connector *connector)
 
 	mutex_lock(&hdmi->mutex);
 	hdmi->force = connector->force;
+	hdmi->last_connector_result = connector->status;
 	dw_hdmi_update_phy_mask(hdmi);
 	mutex_unlock(&hdmi->mutex);
 }
@@ -3046,6 +3050,16 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)
 }
 EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense);
 
+static void dw_hdmi_hpd_work(struct work_struct *work)
+{
+	struct dw_hdmi *hdmi = container_of(work, struct dw_hdmi, hpd_work.work);
+
+	if (hdmi->bridge.dev) {
+		drm_helper_hpd_irq_event(hdmi->bridge.dev);
+		drm_bridge_hpd_notify(&hdmi->bridge, hdmi->last_connector_result);
+	}
+}
+
 static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 {
 	struct dw_hdmi *hdmi = dev_id;
@@ -3097,10 +3111,8 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 			status == connector_status_connected ?
 			"plugin" : "plugout");
 
-		if (hdmi->bridge.dev) {
-			drm_helper_hpd_irq_event(hdmi->bridge.dev);
-			drm_bridge_hpd_notify(&hdmi->bridge, status);
-		}
+		mod_delayed_work(system_percpu_wq, &hdmi->hpd_work,
+				 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
 	}
 
 	hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
@@ -3420,6 +3432,8 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
 		goto err_res;
 	}
 
+	INIT_DELAYED_WORK(&hdmi->hpd_work, dw_hdmi_hpd_work);
+
 	ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq,
 					dw_hdmi_irq, IRQF_SHARED,
 					dev_name(dev), hdmi);
@@ -3552,6 +3566,8 @@ EXPORT_SYMBOL_GPL(dw_hdmi_probe);
 
 void dw_hdmi_remove(struct dw_hdmi *hdmi)
 {
+	disable_delayed_work_sync(&hdmi->hpd_work);
+
 	drm_bridge_remove(&hdmi->bridge);
 
 	if (hdmi->audio && !IS_ERR(hdmi->audio))
-- 
2.53.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH v3 10/13] drm: bridge: dw_hdmi: Use drm_connector_helper_hpd_irq_event()
  2026-04-03 18:52 [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup Jonas Karlman
                   ` (8 preceding siblings ...)
  2026-04-03 18:52 ` [PATCH v3 09/13] drm: bridge: dw_hdmi: Use delayed_work to debounce hotplug event Jonas Karlman
@ 2026-04-03 18:52 ` Jonas Karlman
  2026-04-28 12:40   ` Dmitry Baryshkov
  2026-04-03 18:52 ` [PATCH v3 11/13] drm: bridge: dw_hdmi: Extract dw_hdmi_connector_status_update() Jonas Karlman
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 24+ messages in thread
From: Jonas Karlman @ 2026-04-03 18:52 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: Christian Hewitt, Diederik de Haas, dri-devel, linux-rockchip,
	linux-kernel

Use drm_connector_helper_hpd_irq_event() or drm_helper_hpd_irq_event()
depending on if a dw-hdmi connector or bridge is used.

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
v3: New patch
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 4d079b689b3b..4a0498922476 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -3054,10 +3054,13 @@ static void dw_hdmi_hpd_work(struct work_struct *work)
 {
 	struct dw_hdmi *hdmi = container_of(work, struct dw_hdmi, hpd_work.work);
 
-	if (hdmi->bridge.dev) {
+	if (hdmi->connector.dev)
+		drm_connector_helper_hpd_irq_event(&hdmi->connector);
+	else if (hdmi->bridge.dev)
 		drm_helper_hpd_irq_event(hdmi->bridge.dev);
+
+	if (hdmi->bridge.dev)
 		drm_bridge_hpd_notify(&hdmi->bridge, hdmi->last_connector_result);
-	}
 }
 
 static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
-- 
2.53.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH v3 11/13] drm: bridge: dw_hdmi: Extract dw_hdmi_connector_status_update()
  2026-04-03 18:52 [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup Jonas Karlman
                   ` (9 preceding siblings ...)
  2026-04-03 18:52 ` [PATCH v3 10/13] drm: bridge: dw_hdmi: Use drm_connector_helper_hpd_irq_event() Jonas Karlman
@ 2026-04-03 18:52 ` Jonas Karlman
  2026-04-28 11:42   ` Nicolas Frattaroli
  2026-04-03 18:52 ` [PATCH v3 12/13] drm: bridge: dw_hdmi: Use dw_hdmi_connector_status_update() Jonas Karlman
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 24+ messages in thread
From: Jonas Karlman @ 2026-04-03 18:52 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: Christian Hewitt, Diederik de Haas, dri-devel, linux-rockchip,
	linux-kernel

Move connector EDID update and CEC phys addr handling to a helper
function as a preparation before moving EDID refresh from get_modes
funcs to detect/force funcs.

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
v3: New patch
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 30 +++++++++++++----------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 4a0498922476..0d42fdf9a386 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2467,6 +2467,21 @@ static const struct drm_edid *dw_hdmi_edid_read(struct dw_hdmi *hdmi,
  * DRM Connector Operations
  */
 
+static void
+dw_hdmi_connector_status_update(struct drm_connector *connector,
+				enum drm_connector_status status)
+{
+	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, connector);
+	const struct drm_edid *drm_edid;
+
+	drm_edid = dw_hdmi_edid_read(hdmi, connector);
+	drm_edid_connector_update(connector, drm_edid);
+	drm_edid_free(drm_edid);
+
+	cec_notifier_set_phys_addr(hdmi->cec_notifier,
+				   connector->display_info.source_physical_address);
+}
+
 static enum drm_connector_status
 dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 {
@@ -2484,20 +2499,9 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 
 static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
 {
-	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
-					     connector);
-	const struct drm_edid *drm_edid;
-	int ret;
+	dw_hdmi_connector_status_update(connector, connector->status);
 
-	drm_edid = dw_hdmi_edid_read(hdmi, connector);
-
-	drm_edid_connector_update(connector, drm_edid);
-	cec_notifier_set_phys_addr(hdmi->cec_notifier,
-				   connector->display_info.source_physical_address);
-	ret = drm_edid_connector_add_modes(connector);
-	drm_edid_free(drm_edid);
-
-	return ret;
+	return drm_edid_connector_add_modes(connector);
 }
 
 static int dw_hdmi_connector_atomic_check(struct drm_connector *connector,
-- 
2.53.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH v3 12/13] drm: bridge: dw_hdmi: Use dw_hdmi_connector_status_update()
  2026-04-03 18:52 [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup Jonas Karlman
                   ` (10 preceding siblings ...)
  2026-04-03 18:52 ` [PATCH v3 11/13] drm: bridge: dw_hdmi: Extract dw_hdmi_connector_status_update() Jonas Karlman
@ 2026-04-03 18:52 ` Jonas Karlman
  2026-04-28 11:53   ` Nicolas Frattaroli
  2026-04-28 12:42   ` Dmitry Baryshkov
  2026-04-03 18:52 ` [PATCH v3 13/13] drm: bridge: dw_hdmi: Use display_info is_hdmi and has_audio Jonas Karlman
                   ` (2 subsequent siblings)
  14 siblings, 2 replies; 24+ messages in thread
From: Jonas Karlman @ 2026-04-03 18:52 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: Christian Hewitt, Diederik de Haas, dri-devel, linux-rockchip,
	linux-kernel

Update connector EDID and CEC phys addr from detect and force funcs to
ensure that userspace always have access to latest read EDID after a
sink use a HPD low voltage pulse to indicate that EDID has changed.

With EDID being updated in detect and force funcs, there should no
longer be a need to re-read EDID in get_modes funcs, so drop it.

This change make the dw-hdmi connector work more closely like the bridge
connector does with a hdmi bridge.

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
v3: Reworked 'Update EDID during hotplug processing' patch
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 24 +++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 0d42fdf9a386..5b5654ef6015 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2474,33 +2474,36 @@ dw_hdmi_connector_status_update(struct drm_connector *connector,
 	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, connector);
 	const struct drm_edid *drm_edid;
 
+	if (status == connector_status_disconnected) {
+		drm_edid_connector_update(connector, NULL);
+		cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
+		return;
+	}
+
 	drm_edid = dw_hdmi_edid_read(hdmi, connector);
 	drm_edid_connector_update(connector, drm_edid);
 	drm_edid_free(drm_edid);
 
-	cec_notifier_set_phys_addr(hdmi->cec_notifier,
-				   connector->display_info.source_physical_address);
+	if (status == connector_status_connected)
+		cec_notifier_set_phys_addr(hdmi->cec_notifier,
+				connector->display_info.source_physical_address);
 }
 
 static enum drm_connector_status
 dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 {
-	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
-					     connector);
+	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, connector);
 	enum drm_connector_status status;
 
 	status = dw_hdmi_detect(hdmi);
 
-	if (status == connector_status_disconnected)
-		cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
+	dw_hdmi_connector_status_update(connector, status);
 
 	return status;
 }
 
 static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
 {
-	dw_hdmi_connector_status_update(connector, connector->status);
-
 	return drm_edid_connector_add_modes(connector);
 }
 
@@ -2530,14 +2533,15 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector,
 
 static void dw_hdmi_connector_force(struct drm_connector *connector)
 {
-	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
-					     connector);
+	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, connector);
 
 	mutex_lock(&hdmi->mutex);
 	hdmi->force = connector->force;
 	hdmi->last_connector_result = connector->status;
 	dw_hdmi_update_phy_mask(hdmi);
 	mutex_unlock(&hdmi->mutex);
+
+	dw_hdmi_connector_status_update(connector, connector->status);
 }
 
 static const struct drm_connector_funcs dw_hdmi_connector_funcs = {
-- 
2.53.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* [PATCH v3 13/13] drm: bridge: dw_hdmi: Use display_info is_hdmi and has_audio
  2026-04-03 18:52 [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup Jonas Karlman
                   ` (11 preceding siblings ...)
  2026-04-03 18:52 ` [PATCH v3 12/13] drm: bridge: dw_hdmi: Use dw_hdmi_connector_status_update() Jonas Karlman
@ 2026-04-03 18:52 ` Jonas Karlman
  2026-04-28 12:01   ` Nicolas Frattaroli
  2026-04-12 15:52 ` [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup Bob McChesney
  2026-04-12 16:36 ` Bob McChesney
  14 siblings, 1 reply; 24+ messages in thread
From: Jonas Karlman @ 2026-04-03 18:52 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: Christian Hewitt, Diederik de Haas, dri-devel, linux-rockchip,
	linux-kernel

drm_edid_connector_update() is being called from bridge connector funcs
and from detect and force funcs for dw-hdmi connector.

Change to use is_hdmi and has_audio from display_info directly instead
of keeping our own state in sink_is_hdmi and sink_has_audio.

Also remove the old and unused edid struct member and related define.

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
v3: No change
v2: Collect r-b tag
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 32 ++++-------------------
 1 file changed, 5 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 5b5654ef6015..fecbc386871d 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -44,8 +44,6 @@
 #define DDC_CI_ADDR		0x37
 #define DDC_SEGMENT_ADDR	0x30
 
-#define HDMI_EDID_LEN		512
-
 /* DW-HDMI Controller >= 0x200a are at least compliant with SCDC version 1 */
 #define SCDC_MIN_SOURCE_VERSION	0x1
 
@@ -147,8 +145,6 @@ struct dw_hdmi {
 
 	int vic;
 
-	u8 edid[HDMI_EDID_LEN];
-
 	struct {
 		const struct dw_hdmi_phy_ops *ops;
 		const char *name;
@@ -158,8 +154,6 @@ struct dw_hdmi {
 
 	struct i2c_adapter *ddc;
 	void __iomem *regs;
-	bool sink_is_hdmi;
-	bool sink_has_audio;
 
 	struct pinctrl *pinctrl;
 	struct pinctrl_state *default_state;
@@ -2057,7 +2051,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
 		HDMI_FC_INVIDCONF_IN_I_P_INTERLACED :
 		HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE;
 
-	inv_val |= hdmi->sink_is_hdmi ?
+	inv_val |= display->is_hdmi ?
 		HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE :
 		HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE;
 
@@ -2293,7 +2287,7 @@ static int dw_hdmi_poweron(struct dw_hdmi *hdmi,
 	if (hdmi->hdmi_data.enc_out_bus_format == MEDIA_BUS_FMT_FIXED)
 		hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
 
-	hdmi->hdmi_data.rgb_limited_range = hdmi->sink_is_hdmi &&
+	hdmi->hdmi_data.rgb_limited_range = display->is_hdmi &&
 		drm_default_rgb_quant_range(mode) ==
 		HDMI_QUANTIZATION_RANGE_LIMITED;
 
@@ -2313,7 +2307,7 @@ static int dw_hdmi_poweron(struct dw_hdmi *hdmi,
 	/* HDMI Initialization Step B.3 */
 	dw_hdmi_enable_video_path(hdmi);
 
-	if (hdmi->sink_has_audio) {
+	if (display->has_audio) {
 		dev_dbg(hdmi->dev, "sink has audio support\n");
 
 		/* HDMI Initialization Step E - Configure audio */
@@ -2322,7 +2316,7 @@ static int dw_hdmi_poweron(struct dw_hdmi *hdmi,
 	}
 
 	/* not for DVI mode */
-	if (hdmi->sink_is_hdmi) {
+	if (display->is_hdmi) {
 		dev_dbg(hdmi->dev, "%s HDMI mode\n", __func__);
 
 		/* HDMI Initialization Step F - Configure AVI InfoFrame */
@@ -2436,29 +2430,13 @@ static const struct drm_edid *dw_hdmi_edid_read(struct dw_hdmi *hdmi,
 						struct drm_connector *connector)
 {
 	const struct drm_edid *drm_edid;
-	const struct edid *edid;
 
 	if (!hdmi->ddc)
 		return NULL;
 
 	drm_edid = drm_edid_read_ddc(connector, hdmi->ddc);
-	if (!drm_edid) {
+	if (!drm_edid)
 		dev_dbg(hdmi->dev, "failed to get edid\n");
-		return NULL;
-	}
-
-	/*
-	 * FIXME: This should use connector->display_info.is_hdmi and
-	 * connector->display_info.has_audio from a path that has read the EDID
-	 * and called drm_edid_connector_update().
-	 */
-	edid = drm_edid_raw(drm_edid);
-
-	dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
-		edid->width_cm, edid->height_cm);
-
-	hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
-	hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
 
 	return drm_edid;
 }
-- 
2.53.0


_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup
  2026-04-03 18:52 [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup Jonas Karlman
                   ` (12 preceding siblings ...)
  2026-04-03 18:52 ` [PATCH v3 13/13] drm: bridge: dw_hdmi: Use display_info is_hdmi and has_audio Jonas Karlman
@ 2026-04-12 15:52 ` Bob McChesney
  2026-04-12 16:36 ` Bob McChesney
  14 siblings, 0 replies; 24+ messages in thread
From: Bob McChesney @ 2026-04-12 15:52 UTC (permalink / raw)
  To: Jonas Karlman
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Christian Hewitt,
	Diederik de Haas, dri-devel, linux-rockchip, linux-kernel

On Fri, 03 Apr 2026 18:52:46 +0000, Jonas Karlman <jonas@kwiboo.se> wrote:
> drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup
> 
> This is a revival of an old dw-hdmi series and is the first series part
> of a new effort to upstream old LibreELEC HDMI 2.0 patches for Rockchip
> RK33xx devices.
> 
> This series ensure poweron/poweroff and CEC phys addr invalidation is
> happening under drm mode_config mutex lock, and also ensure EDID is
> updated after a HPD low voltage pulse by changing to debounce hotplug
> processing.
> 
> [...]

Tested-by: Bob McChesney <bob@electricworry.net>

-- 
Bob McChesney <bob@electricworry.net>

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup
  2026-04-03 18:52 [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup Jonas Karlman
                   ` (13 preceding siblings ...)
  2026-04-12 15:52 ` [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup Bob McChesney
@ 2026-04-12 16:36 ` Bob McChesney
  14 siblings, 0 replies; 24+ messages in thread
From: Bob McChesney @ 2026-04-12 16:36 UTC (permalink / raw)
  To: Jonas Karlman
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Christian Hewitt,
	Diederik de Haas, dri-devel, linux-rockchip, linux-kernel

On Fri, 03 Apr 2026 18:52:46 +0000, Jonas Karlman <jonas@kwiboo.se> wrote:
> drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup
> 
> This is a revival of an old dw-hdmi series and is the first series part
> of a new effort to upstream old LibreELEC HDMI 2.0 patches for Rockchip
> RK33xx devices.
> 
> This series ensure poweron/poweroff and CEC phys addr invalidation is
> happening under drm mode_config mutex lock, and also ensure EDID is
> updated after a HPD low voltage pulse by changing to debounce hotplug
> processing.
> 
> [...]

Tested-by: Bob McChesney <bob@electricworry.net>

-- 
Bob McChesney <bob@electricworry.net>

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCH v3 02/13] drm: bridge: dw_hdmi: Only notify connected status on HPD interrupt
  2026-04-03 18:52 ` [PATCH v3 02/13] drm: bridge: dw_hdmi: Only notify connected status on HPD interrupt Jonas Karlman
@ 2026-04-27 18:04   ` Nicolas Frattaroli
  0 siblings, 0 replies; 24+ messages in thread
From: Nicolas Frattaroli @ 2026-04-27 18:04 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, Lucas Stach,
	dri-devel
  Cc: Christian Hewitt, Diederik de Haas, dri-devel, linux-rockchip,
	linux-kernel, Jonas Karlman

On Friday, 3 April 2026 20:52:48 Central European Summer Time Jonas Karlman wrote:
> drm_helper_hpd_irq_event() and drm_bridge_hpd_notify() may incorrectly
> be called with a connected status when HPD is high and RX sense is
> changed. This typically happens when the HDMI cable is unplugged,
> shortly before the HPD is changed to low.
> 
> The original intent of commit da09daf88108 ("drm: bridge: dw_hdmi: only
> trigger hotplug event on link change") was to signal hotplug event at
> correct interrupt states.
> 
> Based on the commit message the intent was to trigger hotplug event:
> - when HPD goes high (plugin)
> - when both HPD and RX sense has gone low (plugout)
> 
> However, following interrupt state changes can typically be observed
> when the HDMI cable is unplugged:
> - RX interrupt:  HPD=high RX=low  -> triggers a connected event
> - HPD interrupt: HPD=low  RX=low  -> triggers a disconnected event
> 
> Fix this by only notify connected status on the HPD interrupt when HPD
> is going high, not on the RX sense interrupt when RX sense is changed.
> 
> After this a connected event should be triggered when HPD=high at HPD
> interrupt, and a disconnected event should be triggered when both
> HPD=low and RX=low at either HPD or RX interrupt.
> 
> Fixes: da09daf88108 ("drm: bridge: dw_hdmi: only trigger hotplug event on link change")
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> ---
> v3: Update commit message
> v2: New patch
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 9febcb58a1df..3b851f12adfe 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -3140,7 +3140,8 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>  			mutex_unlock(&hdmi->cec_notifier_mutex);
>  		}
>  
> -		if (phy_stat & HDMI_PHY_HPD)
> +		if ((intr_stat & HDMI_IH_PHY_STAT0_HPD) &&
> +		    (phy_stat & HDMI_PHY_HPD))
>  			status = connector_status_connected;
>  
>  		if (!(phy_stat & (HDMI_PHY_HPD | HDMI_PHY_RX_SENSE)))
> 

Reviewed-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>




_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCH v3 09/13] drm: bridge: dw_hdmi: Use delayed_work to debounce hotplug event
  2026-04-03 18:52 ` [PATCH v3 09/13] drm: bridge: dw_hdmi: Use delayed_work to debounce hotplug event Jonas Karlman
@ 2026-04-27 18:27   ` Nicolas Frattaroli
  2026-04-28 12:38   ` Dmitry Baryshkov
  1 sibling, 0 replies; 24+ messages in thread
From: Nicolas Frattaroli @ 2026-04-27 18:27 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, dri-devel
  Cc: Christian Hewitt, Diederik de Haas, dri-devel, linux-rockchip,
	linux-kernel, Jonas Karlman

On Friday, 3 April 2026 20:52:55 Central European Summer Time Jonas Karlman wrote:
> HDMI Specification Version 1.4b chapter 8.5 mentions:
> 
>   An HDMI Sink shall not assert high voltage level on its Hot Plug
>   Detect pin when the E-EDID is not available for reading.
> 
>   A Source may use a high voltage level Hot Plug Detect signal to
>   initiate the reading of E-EDID data.
> 
>   An HDMI Sink shall indicate any change to the contents of the E-EDID
>   by driving a low voltage level pulse on the Hot Plug Detect pin. This
>   pulse shall be at least 100 msec.
> 
> Use a work queue to debounce reacting on HPD events to better handle a
> HPD low voltage level pulse when a sink changes the EDID.
> 
> The 1100 msec hotplug debounce timeout was arbitrarily picked to match
> other drivers using same const, and testing using a Raspberry Pi Monitor
> seem to use a 200-300 msec pulse when going from standby to power on
> state.
> 
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> ---
> v3: New patch
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 24 +++++++++++++++++++----
>  1 file changed, 20 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index f3f8144ae98e..4d079b689b3b 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -51,6 +51,8 @@
>  
>  #define HDMI14_MAX_TMDSCLK	340000000
>  
> +#define HOTPLUG_DEBOUNCE_MS	1100
> +
>  static const u16 csc_coeff_default[3][4] = {
>  	{ 0x2000, 0x0000, 0x0000, 0x0000 },
>  	{ 0x0000, 0x2000, 0x0000, 0x0000 },
> @@ -192,6 +194,7 @@ struct dw_hdmi {
>  	hdmi_codec_plugged_cb plugged_cb;
>  	struct device *codec_dev;
>  	enum drm_connector_status last_connector_result;
> +	struct delayed_work hpd_work;
>  };
>  
>  const struct dw_hdmi_plat_data *dw_hdmi_to_plat_data(struct dw_hdmi *hdmi)
> @@ -2528,6 +2531,7 @@ static void dw_hdmi_connector_force(struct drm_connector *connector)
>  
>  	mutex_lock(&hdmi->mutex);
>  	hdmi->force = connector->force;
> +	hdmi->last_connector_result = connector->status;
>  	dw_hdmi_update_phy_mask(hdmi);
>  	mutex_unlock(&hdmi->mutex);
>  }
> @@ -3046,6 +3050,16 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)
>  }
>  EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense);
>  
> +static void dw_hdmi_hpd_work(struct work_struct *work)
> +{
> +	struct dw_hdmi *hdmi = container_of(work, struct dw_hdmi, hpd_work.work);
> +
> +	if (hdmi->bridge.dev) {
> +		drm_helper_hpd_irq_event(hdmi->bridge.dev);
> +		drm_bridge_hpd_notify(&hdmi->bridge, hdmi->last_connector_result);

I think you'll want to `mutex_lock(&hdmi->mutex);` (or better yet,
`guard(mutex)(&hdmi->mutex)` or `scoped_guard(mutex, &hdmi->mutex) {`)
here before reading last_connector_result, otherwise you'll have a
data race with any writers.

> +	}
> +}
> +
>  static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>  {
>  	struct dw_hdmi *hdmi = dev_id;
> @@ -3097,10 +3111,8 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>  			status == connector_status_connected ?
>  			"plugin" : "plugout");
>  
> -		if (hdmi->bridge.dev) {
> -			drm_helper_hpd_irq_event(hdmi->bridge.dev);
> -			drm_bridge_hpd_notify(&hdmi->bridge, status);
> -		}
> +		mod_delayed_work(system_percpu_wq, &hdmi->hpd_work,
> +				 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
>  	}
>  
>  	hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
> @@ -3420,6 +3432,8 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
>  		goto err_res;
>  	}
>  
> +	INIT_DELAYED_WORK(&hdmi->hpd_work, dw_hdmi_hpd_work);
> +
>  	ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq,
>  					dw_hdmi_irq, IRQF_SHARED,
>  					dev_name(dev), hdmi);
> @@ -3552,6 +3566,8 @@ EXPORT_SYMBOL_GPL(dw_hdmi_probe);
>  
>  void dw_hdmi_remove(struct dw_hdmi *hdmi)
>  {
> +	disable_delayed_work_sync(&hdmi->hpd_work);
> +
>  	drm_bridge_remove(&hdmi->bridge);
>  
>  	if (hdmi->audio && !IS_ERR(hdmi->audio))
> 

Kind regards,
Nicolas Frattaroli



_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCH v3 11/13] drm: bridge: dw_hdmi: Extract dw_hdmi_connector_status_update()
  2026-04-03 18:52 ` [PATCH v3 11/13] drm: bridge: dw_hdmi: Extract dw_hdmi_connector_status_update() Jonas Karlman
@ 2026-04-28 11:42   ` Nicolas Frattaroli
  0 siblings, 0 replies; 24+ messages in thread
From: Nicolas Frattaroli @ 2026-04-28 11:42 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, dri-devel
  Cc: Christian Hewitt, Diederik de Haas, dri-devel, linux-rockchip,
	linux-kernel, Jonas Karlman

On Friday, 3 April 2026 20:52:57 Central European Summer Time Jonas Karlman wrote:
> Move connector EDID update and CEC phys addr handling to a helper
> function as a preparation before moving EDID refresh from get_modes
> funcs to detect/force funcs.
> 
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> ---
> v3: New patch
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 30 +++++++++++++----------
>  1 file changed, 17 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 4a0498922476..0d42fdf9a386 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2467,6 +2467,21 @@ static const struct drm_edid *dw_hdmi_edid_read(struct dw_hdmi *hdmi,
>   * DRM Connector Operations
>   */
>  
> +static void
> +dw_hdmi_connector_status_update(struct drm_connector *connector,
> +				enum drm_connector_status status)
> +{
> +	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, connector);
> +	const struct drm_edid *drm_edid;
> +
> +	drm_edid = dw_hdmi_edid_read(hdmi, connector);
> +	drm_edid_connector_update(connector, drm_edid);
> +	drm_edid_free(drm_edid);
> +
> +	cec_notifier_set_phys_addr(hdmi->cec_notifier,
> +				   connector->display_info.source_physical_address);
> +}
> +
>  static enum drm_connector_status
>  dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  {
> @@ -2484,20 +2499,9 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  
>  static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
>  {
> -	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
> -					     connector);
> -	const struct drm_edid *drm_edid;
> -	int ret;
> +	dw_hdmi_connector_status_update(connector, connector->status);
>  
> -	drm_edid = dw_hdmi_edid_read(hdmi, connector);
> -
> -	drm_edid_connector_update(connector, drm_edid);
> -	cec_notifier_set_phys_addr(hdmi->cec_notifier,
> -				   connector->display_info.source_physical_address);
> -	ret = drm_edid_connector_add_modes(connector);
> -	drm_edid_free(drm_edid);
> -
> -	return ret;
> +	return drm_edid_connector_add_modes(connector);
>  }
>  
>  static int dw_hdmi_connector_atomic_check(struct drm_connector *connector,
> 

Reviewed-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>




_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCH v3 12/13] drm: bridge: dw_hdmi: Use dw_hdmi_connector_status_update()
  2026-04-03 18:52 ` [PATCH v3 12/13] drm: bridge: dw_hdmi: Use dw_hdmi_connector_status_update() Jonas Karlman
@ 2026-04-28 11:53   ` Nicolas Frattaroli
  2026-04-28 12:42   ` Dmitry Baryshkov
  1 sibling, 0 replies; 24+ messages in thread
From: Nicolas Frattaroli @ 2026-04-28 11:53 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, dri-devel
  Cc: Christian Hewitt, Diederik de Haas, dri-devel, linux-rockchip,
	linux-kernel, Jonas Karlman

On Friday, 3 April 2026 20:52:58 Central European Summer Time Jonas Karlman wrote:
> Update connector EDID and CEC phys addr from detect and force funcs to
> ensure that userspace always have access to latest read EDID after a
> sink use a HPD low voltage pulse to indicate that EDID has changed.
> 
> With EDID being updated in detect and force funcs, there should no
> longer be a need to re-read EDID in get_modes funcs, so drop it.
> 
> This change make the dw-hdmi connector work more closely like the bridge
> connector does with a hdmi bridge.
> 
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> ---
> v3: Reworked 'Update EDID during hotplug processing' patch
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 24 +++++++++++++----------
>  1 file changed, 14 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 0d42fdf9a386..5b5654ef6015 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2474,33 +2474,36 @@ dw_hdmi_connector_status_update(struct drm_connector *connector,
>  	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, connector);
>  	const struct drm_edid *drm_edid;
>  
> +	if (status == connector_status_disconnected) {
> +		drm_edid_connector_update(connector, NULL);
> +		cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
> +		return;
> +	}
> +
>  	drm_edid = dw_hdmi_edid_read(hdmi, connector);
>  	drm_edid_connector_update(connector, drm_edid);
>  	drm_edid_free(drm_edid);
>  
> -	cec_notifier_set_phys_addr(hdmi->cec_notifier,
> -				   connector->display_info.source_physical_address);
> +	if (status == connector_status_connected)
> +		cec_notifier_set_phys_addr(hdmi->cec_notifier,
> +				connector->display_info.source_physical_address);
>  }
>  
>  static enum drm_connector_status
>  dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
>  {
> -	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
> -					     connector);
> +	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, connector);
>  	enum drm_connector_status status;
>  
>  	status = dw_hdmi_detect(hdmi);
>  
> -	if (status == connector_status_disconnected)
> -		cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
> +	dw_hdmi_connector_status_update(connector, status);
>  
>  	return status;
>  }
>  
>  static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
>  {
> -	dw_hdmi_connector_status_update(connector, connector->status);
> -
>  	return drm_edid_connector_add_modes(connector);
>  }

Are we absolutely sure status_update is called before this, so that the
EDID doesn't need to be re-read? E.g. drm_connector_helper_get_modes
does do an EDID read beforehand.

Speaking of which: if we had connector->ddc set, we could just use
drm_connector_helper_get_modes for this callback. But maybe it's not
worth spending the time refactoring the resource handling around
hdmi->ddc when the eventual goal is to refactor this all into using
a bridge connector anyway.

>  
> @@ -2530,14 +2533,15 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector,
>  
>  static void dw_hdmi_connector_force(struct drm_connector *connector)
>  {
> -	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
> -					     connector);
> +	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, connector);
>  
>  	mutex_lock(&hdmi->mutex);
>  	hdmi->force = connector->force;
>  	hdmi->last_connector_result = connector->status;
>  	dw_hdmi_update_phy_mask(hdmi);
>  	mutex_unlock(&hdmi->mutex);
> +
> +	dw_hdmi_connector_status_update(connector, connector->status);
>  }
>  
>  static const struct drm_connector_funcs dw_hdmi_connector_funcs = {
> 





_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCH v3 13/13] drm: bridge: dw_hdmi: Use display_info is_hdmi and has_audio
  2026-04-03 18:52 ` [PATCH v3 13/13] drm: bridge: dw_hdmi: Use display_info is_hdmi and has_audio Jonas Karlman
@ 2026-04-28 12:01   ` Nicolas Frattaroli
  0 siblings, 0 replies; 24+ messages in thread
From: Nicolas Frattaroli @ 2026-04-28 12:01 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, dri-devel
  Cc: Christian Hewitt, Diederik de Haas, dri-devel, linux-rockchip,
	linux-kernel, Jonas Karlman

On Friday, 3 April 2026 20:52:59 Central European Summer Time Jonas Karlman wrote:
> drm_edid_connector_update() is being called from bridge connector funcs
> and from detect and force funcs for dw-hdmi connector.
> 
> Change to use is_hdmi and has_audio from display_info directly instead
> of keeping our own state in sink_is_hdmi and sink_has_audio.
> 
> Also remove the old and unused edid struct member and related define.
> 
> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> ---
> v3: No change
> v2: Collect r-b tag
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 32 ++++-------------------
>  1 file changed, 5 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 5b5654ef6015..fecbc386871d 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -44,8 +44,6 @@
>  #define DDC_CI_ADDR		0x37
>  #define DDC_SEGMENT_ADDR	0x30
>  
> -#define HDMI_EDID_LEN		512
> -
>  /* DW-HDMI Controller >= 0x200a are at least compliant with SCDC version 1 */
>  #define SCDC_MIN_SOURCE_VERSION	0x1
>  
> @@ -147,8 +145,6 @@ struct dw_hdmi {
>  
>  	int vic;
>  
> -	u8 edid[HDMI_EDID_LEN];
> -
>  	struct {
>  		const struct dw_hdmi_phy_ops *ops;
>  		const char *name;
> @@ -158,8 +154,6 @@ struct dw_hdmi {
>  
>  	struct i2c_adapter *ddc;
>  	void __iomem *regs;
> -	bool sink_is_hdmi;
> -	bool sink_has_audio;
>  
>  	struct pinctrl *pinctrl;
>  	struct pinctrl_state *default_state;
> @@ -2057,7 +2051,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
>  		HDMI_FC_INVIDCONF_IN_I_P_INTERLACED :
>  		HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE;
>  
> -	inv_val |= hdmi->sink_is_hdmi ?
> +	inv_val |= display->is_hdmi ?
>  		HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE :
>  		HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE;
>  
> @@ -2293,7 +2287,7 @@ static int dw_hdmi_poweron(struct dw_hdmi *hdmi,
>  	if (hdmi->hdmi_data.enc_out_bus_format == MEDIA_BUS_FMT_FIXED)
>  		hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
>  
> -	hdmi->hdmi_data.rgb_limited_range = hdmi->sink_is_hdmi &&
> +	hdmi->hdmi_data.rgb_limited_range = display->is_hdmi &&
>  		drm_default_rgb_quant_range(mode) ==
>  		HDMI_QUANTIZATION_RANGE_LIMITED;
>  
> @@ -2313,7 +2307,7 @@ static int dw_hdmi_poweron(struct dw_hdmi *hdmi,
>  	/* HDMI Initialization Step B.3 */
>  	dw_hdmi_enable_video_path(hdmi);
>  
> -	if (hdmi->sink_has_audio) {
> +	if (display->has_audio) {
>  		dev_dbg(hdmi->dev, "sink has audio support\n");
>  
>  		/* HDMI Initialization Step E - Configure audio */
> @@ -2322,7 +2316,7 @@ static int dw_hdmi_poweron(struct dw_hdmi *hdmi,
>  	}
>  
>  	/* not for DVI mode */
> -	if (hdmi->sink_is_hdmi) {
> +	if (display->is_hdmi) {
>  		dev_dbg(hdmi->dev, "%s HDMI mode\n", __func__);
>  
>  		/* HDMI Initialization Step F - Configure AVI InfoFrame */
> @@ -2436,29 +2430,13 @@ static const struct drm_edid *dw_hdmi_edid_read(struct dw_hdmi *hdmi,
>  						struct drm_connector *connector)
>  {
>  	const struct drm_edid *drm_edid;
> -	const struct edid *edid;
>  
>  	if (!hdmi->ddc)
>  		return NULL;
>  
>  	drm_edid = drm_edid_read_ddc(connector, hdmi->ddc);
> -	if (!drm_edid) {
> +	if (!drm_edid)
>  		dev_dbg(hdmi->dev, "failed to get edid\n");
> -		return NULL;
> -	}
> -
> -	/*
> -	 * FIXME: This should use connector->display_info.is_hdmi and
> -	 * connector->display_info.has_audio from a path that has read the EDID
> -	 * and called drm_edid_connector_update().
> -	 */
> -	edid = drm_edid_raw(drm_edid);
> -
> -	dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
> -		edid->width_cm, edid->height_cm);
> -
> -	hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
> -	hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
>  
>  	return drm_edid;
>  }
> 

Reviewed-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>




_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCH v3 09/13] drm: bridge: dw_hdmi: Use delayed_work to debounce hotplug event
  2026-04-03 18:52 ` [PATCH v3 09/13] drm: bridge: dw_hdmi: Use delayed_work to debounce hotplug event Jonas Karlman
  2026-04-27 18:27   ` Nicolas Frattaroli
@ 2026-04-28 12:38   ` Dmitry Baryshkov
  1 sibling, 0 replies; 24+ messages in thread
From: Dmitry Baryshkov @ 2026-04-28 12:38 UTC (permalink / raw)
  To: Jonas Karlman
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Christian Hewitt,
	Diederik de Haas, dri-devel, linux-rockchip, linux-kernel

On Fri, Apr 03, 2026 at 06:52:55PM +0000, Jonas Karlman wrote:
> HDMI Specification Version 1.4b chapter 8.5 mentions:
> 
>   An HDMI Sink shall not assert high voltage level on its Hot Plug
>   Detect pin when the E-EDID is not available for reading.
> 
>   A Source may use a high voltage level Hot Plug Detect signal to
>   initiate the reading of E-EDID data.
> 
>   An HDMI Sink shall indicate any change to the contents of the E-EDID
>   by driving a low voltage level pulse on the Hot Plug Detect pin. This
>   pulse shall be at least 100 msec.
> 
> Use a work queue to debounce reacting on HPD events to better handle a
> HPD low voltage level pulse when a sink changes the EDID.
> 
> The 1100 msec hotplug debounce timeout was arbitrarily picked to match
> other drivers using same const, and testing using a Raspberry Pi Monitor
> seem to use a 200-300 msec pulse when going from standby to power on
> state.
> 
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> ---
> v3: New patch
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 24 +++++++++++++++++++----
>  1 file changed, 20 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index f3f8144ae98e..4d079b689b3b 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -51,6 +51,8 @@
>  
>  #define HDMI14_MAX_TMDSCLK	340000000
>  
> +#define HOTPLUG_DEBOUNCE_MS	1100
> +
>  static const u16 csc_coeff_default[3][4] = {
>  	{ 0x2000, 0x0000, 0x0000, 0x0000 },
>  	{ 0x0000, 0x2000, 0x0000, 0x0000 },
> @@ -192,6 +194,7 @@ struct dw_hdmi {
>  	hdmi_codec_plugged_cb plugged_cb;
>  	struct device *codec_dev;
>  	enum drm_connector_status last_connector_result;
> +	struct delayed_work hpd_work;
>  };
>  
>  const struct dw_hdmi_plat_data *dw_hdmi_to_plat_data(struct dw_hdmi *hdmi)
> @@ -2528,6 +2531,7 @@ static void dw_hdmi_connector_force(struct drm_connector *connector)
>  
>  	mutex_lock(&hdmi->mutex);
>  	hdmi->force = connector->force;
> +	hdmi->last_connector_result = connector->status;
>  	dw_hdmi_update_phy_mask(hdmi);
>  	mutex_unlock(&hdmi->mutex);
>  }
> @@ -3046,6 +3050,16 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)
>  }
>  EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense);
>  
> +static void dw_hdmi_hpd_work(struct work_struct *work)
> +{
> +	struct dw_hdmi *hdmi = container_of(work, struct dw_hdmi, hpd_work.work);
> +
> +	if (hdmi->bridge.dev) {
> +		drm_helper_hpd_irq_event(hdmi->bridge.dev);

Nit: please consider this for the followup cleanup. The
drm_helper_hpd_irq_event() is not very effective: we already know which
bridge (and thus connector) caused the HPD event.

Moreover, the call should be redundant as drm_bridge_hpd_notify will
call the registered callback, which normally would be
drm_bridge_connector_hpd_cb(). Internally, this function calls
drm_kms_helper_connector_hotplug_event().

> +		drm_bridge_hpd_notify(&hdmi->bridge, hdmi->last_connector_result);
> +	}
> +}
> +
>  static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>  {
>  	struct dw_hdmi *hdmi = dev_id;
> @@ -3097,10 +3111,8 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>  			status == connector_status_connected ?
>  			"plugin" : "plugout");
>  
> -		if (hdmi->bridge.dev) {
> -			drm_helper_hpd_irq_event(hdmi->bridge.dev);
> -			drm_bridge_hpd_notify(&hdmi->bridge, status);
> -		}
> +		mod_delayed_work(system_percpu_wq, &hdmi->hpd_work,
> +				 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
>  	}
>  
>  	hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
> @@ -3420,6 +3432,8 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
>  		goto err_res;
>  	}
>  
> +	INIT_DELAYED_WORK(&hdmi->hpd_work, dw_hdmi_hpd_work);
> +
>  	ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq,
>  					dw_hdmi_irq, IRQF_SHARED,
>  					dev_name(dev), hdmi);
> @@ -3552,6 +3566,8 @@ EXPORT_SYMBOL_GPL(dw_hdmi_probe);
>  
>  void dw_hdmi_remove(struct dw_hdmi *hdmi)
>  {
> +	disable_delayed_work_sync(&hdmi->hpd_work);
> +
>  	drm_bridge_remove(&hdmi->bridge);
>  
>  	if (hdmi->audio && !IS_ERR(hdmi->audio))
> -- 
> 2.53.0
> 

-- 
With best wishes
Dmitry

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCH v3 10/13] drm: bridge: dw_hdmi: Use drm_connector_helper_hpd_irq_event()
  2026-04-03 18:52 ` [PATCH v3 10/13] drm: bridge: dw_hdmi: Use drm_connector_helper_hpd_irq_event() Jonas Karlman
@ 2026-04-28 12:40   ` Dmitry Baryshkov
  0 siblings, 0 replies; 24+ messages in thread
From: Dmitry Baryshkov @ 2026-04-28 12:40 UTC (permalink / raw)
  To: Jonas Karlman
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Christian Hewitt,
	Diederik de Haas, dri-devel, linux-rockchip, linux-kernel

On Fri, Apr 03, 2026 at 06:52:56PM +0000, Jonas Karlman wrote:
> Use drm_connector_helper_hpd_irq_event() or drm_helper_hpd_irq_event()
> depending on if a dw-hdmi connector or bridge is used.
> 
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> ---
> v3: New patch
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 4d079b689b3b..4a0498922476 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -3054,10 +3054,13 @@ static void dw_hdmi_hpd_work(struct work_struct *work)
>  {
>  	struct dw_hdmi *hdmi = container_of(work, struct dw_hdmi, hpd_work.work);
>  
> -	if (hdmi->bridge.dev) {
> +	if (hdmi->connector.dev)
> +		drm_connector_helper_hpd_irq_event(&hdmi->connector);
> +	else if (hdmi->bridge.dev)
>  		drm_helper_hpd_irq_event(hdmi->bridge.dev);

Okay, following the comment to the previous patch it should rather
become:

	if (hdmi->bridge.dev)
		drm_bridge_hpd_notify(&hdmi->bridge, hdmi->last_connector_result);
	else if (hdmi->connector.dev)
		drm_connector_helper_hpd_irq_event(&hdmi->connector);


> +
> +	if (hdmi->bridge.dev)
>  		drm_bridge_hpd_notify(&hdmi->bridge, hdmi->last_connector_result);
> -	}
>  }
>  
>  static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
> -- 
> 2.53.0
> 

-- 
With best wishes
Dmitry

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

* Re: [PATCH v3 12/13] drm: bridge: dw_hdmi: Use dw_hdmi_connector_status_update()
  2026-04-03 18:52 ` [PATCH v3 12/13] drm: bridge: dw_hdmi: Use dw_hdmi_connector_status_update() Jonas Karlman
  2026-04-28 11:53   ` Nicolas Frattaroli
@ 2026-04-28 12:42   ` Dmitry Baryshkov
  1 sibling, 0 replies; 24+ messages in thread
From: Dmitry Baryshkov @ 2026-04-28 12:42 UTC (permalink / raw)
  To: Jonas Karlman
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Christian Hewitt,
	Diederik de Haas, dri-devel, linux-rockchip, linux-kernel

On Fri, Apr 03, 2026 at 06:52:58PM +0000, Jonas Karlman wrote:
> Update connector EDID and CEC phys addr from detect and force funcs to
> ensure that userspace always have access to latest read EDID after a
> sink use a HPD low voltage pulse to indicate that EDID has changed.
> 
> With EDID being updated in detect and force funcs, there should no
> longer be a need to re-read EDID in get_modes funcs, so drop it.
> 
> This change make the dw-hdmi connector work more closely like the bridge
> connector does with a hdmi bridge.

Please consider using drm_atomic_helper_connector_hdmi_update()
directly.


> 
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> ---
> v3: Reworked 'Update EDID during hotplug processing' patch
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 24 +++++++++++++----------
>  1 file changed, 14 insertions(+), 10 deletions(-)
> 

-- 
With best wishes
Dmitry

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

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

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

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-03 18:52 [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup Jonas Karlman
2026-04-03 18:52 ` [PATCH v3 01/13] drm: bridge: dw_hdmi: Disable scrambler feature when not supported Jonas Karlman
2026-04-03 18:52 ` [PATCH v3 02/13] drm: bridge: dw_hdmi: Only notify connected status on HPD interrupt Jonas Karlman
2026-04-27 18:04   ` Nicolas Frattaroli
2026-04-03 18:52 ` [PATCH v3 03/13] drm: bridge: dw_hdmi: Call poweron/poweroff from atomic enable/disable Jonas Karlman
2026-04-03 18:52 ` [PATCH v3 04/13] drm: bridge: dw_hdmi: Use passed mode instead of stored previous_mode Jonas Karlman
2026-04-03 18:52 ` [PATCH v3 05/13] drm: bridge: dw_hdmi: Fold poweron and setup functions Jonas Karlman
2026-04-03 18:52 ` [PATCH v3 06/13] drm: bridge: dw_hdmi: Remove previous_mode and mode_set Jonas Karlman
2026-04-03 18:52 ` [PATCH v3 07/13] drm: bridge: dw_hdmi: Invalidate CEC phys addr from connector detect Jonas Karlman
2026-04-03 18:52 ` [PATCH v3 08/13] drm: bridge: dw_hdmi: Remove cec_notifier_mutex Jonas Karlman
2026-04-03 18:52 ` [PATCH v3 09/13] drm: bridge: dw_hdmi: Use delayed_work to debounce hotplug event Jonas Karlman
2026-04-27 18:27   ` Nicolas Frattaroli
2026-04-28 12:38   ` Dmitry Baryshkov
2026-04-03 18:52 ` [PATCH v3 10/13] drm: bridge: dw_hdmi: Use drm_connector_helper_hpd_irq_event() Jonas Karlman
2026-04-28 12:40   ` Dmitry Baryshkov
2026-04-03 18:52 ` [PATCH v3 11/13] drm: bridge: dw_hdmi: Extract dw_hdmi_connector_status_update() Jonas Karlman
2026-04-28 11:42   ` Nicolas Frattaroli
2026-04-03 18:52 ` [PATCH v3 12/13] drm: bridge: dw_hdmi: Use dw_hdmi_connector_status_update() Jonas Karlman
2026-04-28 11:53   ` Nicolas Frattaroli
2026-04-28 12:42   ` Dmitry Baryshkov
2026-04-03 18:52 ` [PATCH v3 13/13] drm: bridge: dw_hdmi: Use display_info is_hdmi and has_audio Jonas Karlman
2026-04-28 12:01   ` Nicolas Frattaroli
2026-04-12 15:52 ` [PATCH v3 00/13] drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup Bob McChesney
2026-04-12 16:36 ` Bob McChesney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox