* [PATCH] drm/i915/hdmi: preserve cached EDID on DDC failure when connector is forced
@ 2026-10-24 12:06 Aman Sharma
2026-10-24 12:19 ` sashiko-bot
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Aman Sharma @ 2026-10-24 12:06 UTC (permalink / raw)
To: intel-gfx, dri-devel
Cc: Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
David Airlie, Simona Vetter, linux-kernel, Aman Sharma
When an HDMI connector is forced enabled (e.g. via video=HDMI-A-1:e for
laptop clamshell operation) and the external monitor enters DPMS standby,
some monitors (such as the BenQ GW2790Q) power down their internal DDC/I2C
controller, causing SCDC/EDID reads to fail with -ENXIO (-6).
Currently, intel_hdmi_force() unconditionally calls intel_hdmi_unset_edid()
before calling intel_hdmi_set_edid(). When drm_edid_read_ddc() returns NULL
during monitor standby, the connector's cached detect_edid is wiped out and
drm_helper_probe_single_connector_modes() falls back to the 1024x768 VESA
no-EDID mode. When the monitor wakes back up, because the connector status
remained forced to connector_status_connected, no hotplug state transition
occurs and the display remains stuck at 1024x768 until a manual mode probe
(such as toggling the laptop lid) is triggered.
Fix this by retaining the previously cached detect_edid when a DDC read
fails on a forced-on connector. When the monitor is awake or a different
monitor is plugged in, drm_edid_read_ddc() succeeds and replaces the
cached EDID normally.
Signed-off-by: Aman Sharma <amansharma6122002@gmail.com>
---
drivers/gpu/drm/i915/display/intel_hdmi.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index b6fa1a1558b8..140d98a61a9c 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2570,6 +2570,18 @@ intel_hdmi_set_edid(struct drm_connector *_connector)
intel_gmbus_force_bit(ddc, false);
}
+ /*
+ * If the connector is forced on (e.g. video=HDMI-A-1:e) and the sink's
+ * DDC/I2C bus is powered down during DPMS standby, keep the previously
+ * cached EDID rather than wiping it and falling back to 1024x768.
+ */
+ if (!drm_edid && connector->base.force && connector->detect_edid) {
+ intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref);
+ return true;
+ }
+
+ drm_edid_free(connector->detect_edid);
+
/* Below we depend on display info having been updated */
drm_edid_connector_update(&connector->base, drm_edid);
@@ -2638,10 +2650,10 @@ intel_hdmi_force(struct drm_connector *_connector)
if (!intel_display_driver_check_access(display))
return;
- intel_hdmi_unset_edid(&connector->base);
-
- if (connector->base.status != connector_status_connected)
+ if (connector->base.status != connector_status_connected) {
+ intel_hdmi_unset_edid(&connector->base);
return;
+ }
intel_hdmi_set_edid(&connector->base);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH] drm/i915/hdmi: preserve cached EDID on DDC failure when connector is forced 2026-10-24 12:06 [PATCH] drm/i915/hdmi: preserve cached EDID on DDC failure when connector is forced Aman Sharma @ 2026-10-24 12:19 ` sashiko-bot 2026-10-24 12:33 ` [PATCH v2] " Aman Sharma 2026-10-27 15:13 ` ✗ LGCI.VerificationFailed: failure for drm/i915/hdmi: preserve cached EDID on DDC failure when connector is forced (rev2) Patchwork 2 siblings, 0 replies; 7+ messages in thread From: sashiko-bot @ 2026-10-24 12:19 UTC (permalink / raw) To: Aman Sharma, intel-gfx, dri-devel Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider: - [Medium] drm/i915/hdmi: cached EDID still wiped by intel_hdmi_detect() on hotplug - [Medium] drm/i915/hdmi: stale dp_dual_mode state in intel_hdmi_force() - [Medium] drm/i915/hdmi: stale detect_edid retained after Gen11+ disconnect -- commit 3cd457134d1b7d17ad43e200eb7f55647f7587b7 Author: Aman Sharma <amansharma6122002@gmail.com> drm/i915/hdmi: preserve cached EDID on DDC failure when connector is forced This commit retains the previously cached connector->detect_edid when a DDC read fails on a forced-on HDMI connector instead of unconditionally clearing it in intel_hdmi_force(). This avoids wiping the cached EDID and falling back to the 1024x768 no-EDID mode when an external monitor powers down its DDC/I2C controller during DPMS standby. > diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c > index b6fa1a1558b82..140d98a61a9c6 100644 > --- a/drivers/gpu/drm/i915/display/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c > @@ -2568,6 +2568,18 @@ intel_hdmi_set_edid(struct drm_connector *_connector) > intel_gmbus_force_bit(ddc, false); > } > > + /* > + * If the connector is forced on (e.g. video=HDMI-A-1:e) and the sink's > + * DDC/I2C bus is powered down during DPMS standby, keep the previously > + * cached EDID rather than wiping it and falling back to 1024x768. > + */ > + if (!drm_edid && connector->base.force && connector->detect_edid) { > + intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref); > + return true; > + } [Severity: Medium] Will this check ever trigger when intel_hdmi_set_edid() is called from the hotplug detection path, or will intel_hdmi_detect() still wipe connector->detect_edid on hotplug? Even when connector->base.force is set, hotplug and poll handling in drivers/gpu/drm/i915/display/intel_hotplug.c still runs intel_hotplug_detect_connector() -> drm_helper_probe_detect() -> intel_hdmi_detect(): drivers/gpu/drm/i915/display/intel_hotplug.c:intel_hotplug_detect_connector() { ... status = drm_helper_probe_detect(&connector->base, NULL, false); if (!connector->base.force) connector->base.status = status; ... } In drivers/gpu/drm/i915/display/intel_hdmi.c, intel_hdmi_detect() is the only caller that checks the boolean return value of intel_hdmi_set_edid(), and it still unconditionally calls intel_hdmi_unset_edid() first: drivers/gpu/drm/i915/display/intel_hdmi.c:intel_hdmi_detect() { ... if (DISPLAY_VER(display) >= 11 && !intel_digital_port_connected(encoder)) goto out; intel_hdmi_unset_edid(&connector->base); if (intel_hdmi_set_edid(&connector->base)) status = connector_status_connected; ... } On DISPLAY_VER(display) < 11, or on DISPLAY_VER(display) >= 11 when intel_digital_port_connected(encoder) is true during standby or wake-up while DDC is still powered down, intel_hdmi_unset_edid() frees connector->detect_edid and sets it to NULL before intel_hdmi_set_edid() is called. When intel_hdmi_set_edid() then sees connector->detect_edid == NULL, it calls drm_edid_connector_update(&connector->base, NULL) and returns false. Because drm_helper_probe_detect_ctx() sees the returned status differ from the forced connector->status, it increments connector->epoch_counter and triggers a hotplug uevent, causing the subsequent userspace mode probe to find connector->detect_edid already cleared and fall back to 1024x768 anyway. Should intel_hdmi_detect() also avoid calling intel_hdmi_unset_edid() up front so that connector->detect_edid is preserved across hotplug detection on a forced connector? [Severity: Medium] Can this early return also leave connector->detect_edid out of sync with connector->base.edid_blob_ptr if an unforced connector on DISPLAY_VER >= 11 is unplugged and later forced on? In drivers/gpu/drm/i915/display/intel_hdmi.c, when a sink is disconnected on DISPLAY_VER(display) >= 11, intel_hdmi_detect() jumps to out before calling intel_hdmi_unset_edid(): drivers/gpu/drm/i915/display/intel_hdmi.c:intel_hdmi_detect() { ... if (DISPLAY_VER(display) >= 11 && !intel_digital_port_connected(encoder)) goto out; intel_hdmi_unset_edid(&connector->base); ... } When the connector is not forced, drm_helper_probe_single_connector_modes() in drivers/gpu/drm/drm_probe_helper.c handles connector_status_disconnected by clearing the EDID property to NULL while connector->detect_edid remains non-NULL: drivers/gpu/drm/drm_probe_helper.c:drm_helper_probe_single_connector_modes() { ... if (connector->status == connector_status_disconnected) { drm_dbg_kms(dev, "[CONNECTOR:%d:%s] disconnected\n", connector->base.id, connector->name); drm_connector_update_edid_property(connector, NULL); drm_mode_prune_invalid(dev, &connector->modes, false); goto exit; } ... } If the user subsequently forces the connector on (for example via sysfs) while disconnected or while DDC fails, drm_helper_probe_single_connector_modes() calls intel_hdmi_force() -> intel_hdmi_set_edid(). Because connector->detect_edid is still non-NULL from the previously unplugged monitor, intel_hdmi_set_edid() will hit this early return without calling drm_edid_connector_update(), retaining the unplugged monitor's stale connector->detect_edid while connector->base.edid_blob_ptr remains NULL. > + > + drm_edid_free(connector->detect_edid); > + > /* Below we depend on display info having been updated */ > drm_edid_connector_update(&connector->base, drm_edid); > > @@ -2638,10 +2650,10 @@ intel_hdmi_force(struct drm_connector *_connector) > if (!intel_display_driver_check_access(display)) > return; > > - intel_hdmi_unset_edid(&connector->base); > - > - if (connector->base.status != connector_status_connected) > + if (connector->base.status != connector_status_connected) { > + intel_hdmi_unset_edid(&connector->base); > return; > + } > > intel_hdmi_set_edid(&connector->base); > } [Severity: Medium] Does skipping intel_hdmi_unset_edid() in intel_hdmi_force() when connector->base.status == connector_status_connected leave stale intel_hdmi->dp_dual_mode state behind when a new EDID is read? Previously, intel_hdmi_force() called intel_hdmi_unset_edid(), which resets intel_hdmi->dp_dual_mode in addition to freeing connector->detect_edid: drivers/gpu/drm/i915/display/intel_hdmi.c:intel_hdmi_unset_edid() { ... intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE; intel_hdmi->dp_dual_mode.max_tmds_clock = 0; drm_edid_free(connector->detect_edid); connector->detect_edid = NULL; } When intel_hdmi_force() instead calls intel_hdmi_set_edid() directly and a new EDID is read, intel_hdmi_set_edid() frees connector->detect_edid and calls intel_hdmi_dp_dual_mode_detect(), which returns early without clearing hdmi->dp_dual_mode when type == DRM_DP_DUAL_MODE_NONE: drivers/gpu/drm/i915/display/intel_hdmi.c:intel_hdmi_dp_dual_mode_detect() { ... if (type == DRM_DP_DUAL_MODE_NONE) return; hdmi->dp_dual_mode.type = type; hdmi->dp_dual_mode.max_tmds_clock = drm_dp_dual_mode_max_tmds_clock(display->drm, type, ddc); ... } If a DP++ adaptor was previously connected, or if an unforced connector had assumed DRM_DP_DUAL_MODE_TYPE1_DVI from VBT before being forced on via sysfs, won't intel_hdmi->dp_dual_mode.type and intel_hdmi->dp_dual_mode.max_tmds_clock retain their old values, causing hdmi_port_clock_limit() to clamp the maximum TMDS clock and intel_dp_dual_mode_set_tmds_output() to send DP++ I2C writes to a native HDMI sink? -- Sashiko AI review · https://sashiko.dev/#/patchset/179284356403.1659508.10439113185286055496@gmail.com?part=1 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2] drm/i915/hdmi: preserve cached EDID on DDC failure when connector is forced 2026-10-24 12:06 [PATCH] drm/i915/hdmi: preserve cached EDID on DDC failure when connector is forced Aman Sharma 2026-10-24 12:19 ` sashiko-bot @ 2026-10-24 12:33 ` Aman Sharma 2026-10-24 12:47 ` sashiko-bot 2026-10-24 12:53 ` [PATCH v3] " Aman Sharma 2026-10-27 15:13 ` ✗ LGCI.VerificationFailed: failure for drm/i915/hdmi: preserve cached EDID on DDC failure when connector is forced (rev2) Patchwork 2 siblings, 2 replies; 7+ messages in thread From: Aman Sharma @ 2026-10-24 12:33 UTC (permalink / raw) To: intel-gfx, dri-devel Cc: Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin, David Airlie, Simona Vetter, linux-kernel, Aman Sharma When an HDMI connector is forced enabled (e.g. via video=HDMI-A-1:e for laptop clamshell operation) and the external monitor enters DPMS standby, some monitors (such as the BenQ GW2790Q) power down their internal DDC/I2C controller, causing SCDC/EDID reads to fail with -ENXIO (-6). Currently, intel_hdmi_detect() and intel_hdmi_force() unconditionally call intel_hdmi_unset_edid() before calling intel_hdmi_set_edid(). When drm_edid_read_ddc() returns NULL during monitor standby, the connector's cached detect_edid is wiped out and drm_helper_probe_single_connector_modes() falls back to the 1024x768 VESA no-EDID mode. When the monitor wakes back up, because the connector status remained forced to connector_status_connected, no hotplug state transition occurs and the display remains stuck at 1024x768 until a manual mode probe (such as toggling the laptop lid) is triggered. Fix this by moving intel_hdmi_unset_edid() into intel_hdmi_set_edid() after checking whether a forced connector already has a valid cached EDID (detect_edid and edid_blob_ptr) when DDC fails, and only clearing detect_edid on Gen11+ digital port disconnect when the connector is not forced. When the monitor is awake or a different monitor is plugged in, drm_edid_read_ddc() succeeds, resets the previous EDID and dp_dual_mode state via intel_hdmi_unset_edid(), and updates the connector with the new EDID. v2: - Move intel_hdmi_unset_edid() into intel_hdmi_set_edid() so hotplug detection via intel_hdmi_detect() also preserves the cached EDID on forced connectors and resets dp_dual_mode when updating EDID. - Clear detect_edid on Gen11+ disconnect when the connector is unforced, and verify edid_blob_ptr is non-NULL before retaining detect_edid. Signed-off-by: Aman Sharma <amansharma6122002@gmail.com> --- drivers/gpu/drm/i915/display/intel_hdmi.c | 25 +++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index b6fa1a1558b8..89ab9a790a41 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -2570,6 +2570,19 @@ intel_hdmi_set_edid(struct drm_connector *_connector) intel_gmbus_force_bit(ddc, false); } + /* + * If the connector is forced on (e.g. video=HDMI-A-1:e) and the sink's + * DDC/I2C bus is powered down during DPMS standby, keep the previously + * cached EDID rather than wiping it and falling back to 1024x768. + */ + if (!drm_edid && connector->base.force && + connector->detect_edid && connector->base.edid_blob_ptr) { + intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref); + return true; + } + + intel_hdmi_unset_edid(&connector->base); + /* Below we depend on display info having been updated */ drm_edid_connector_update(&connector->base, drm_edid); @@ -2611,10 +2624,11 @@ intel_hdmi_detect(struct drm_connector *_connector, bool force) wakeref = intel_display_power_get(display, POWER_DOMAIN_GMBUS); if (DISPLAY_VER(display) >= 11 && - !intel_digital_port_connected(encoder)) + !intel_digital_port_connected(encoder)) { + if (!connector->base.force) + intel_hdmi_unset_edid(&connector->base); goto out; - - intel_hdmi_unset_edid(&connector->base); + } if (intel_hdmi_set_edid(&connector->base)) status = connector_status_connected; @@ -2638,10 +2652,10 @@ intel_hdmi_force(struct drm_connector *_connector) if (!intel_display_driver_check_access(display)) return; - intel_hdmi_unset_edid(&connector->base); - - if (connector->base.status != connector_status_connected) + if (connector->base.status != connector_status_connected) { + intel_hdmi_unset_edid(&connector->base); return; + } intel_hdmi_set_edid(&connector->base); } -- 2.43.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2] drm/i915/hdmi: preserve cached EDID on DDC failure when connector is forced 2026-10-24 12:33 ` [PATCH v2] " Aman Sharma @ 2026-10-24 12:47 ` sashiko-bot 2026-10-24 12:53 ` [PATCH v3] " Aman Sharma 1 sibling, 0 replies; 7+ messages in thread From: sashiko-bot @ 2026-10-24 12:47 UTC (permalink / raw) To: Aman Sharma, intel-gfx, dri-devel Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: - [Medium] drm/i915/hdmi: DRM_FORCE_OFF treated as forced-on in intel_hdmi_set_edid() - [Medium] drm/i915/hdmi: CEC invalidation and hotplug churn in intel_hdmi_detect() -- commit fa3007d46f607179adb22d75054bb3efa254e38b Author: Aman Sharma <amansharma6122002@gmail.com> drm/i915/hdmi: preserve cached EDID on DDC failure when connector is forced This commit preserves the cached detect_edid on forced HDMI connectors when DDC reads fail during monitor standby, moving intel_hdmi_unset_edid() into intel_hdmi_set_edid() and skipping EDID teardown on Gen11+ disconnect when the connector is forced. > diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c > index b6fa1a1558b82..89ab9a790a419 100644 > --- a/drivers/gpu/drm/i915/display/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c > @@ -2568,6 +2568,19 @@ intel_hdmi_set_edid(struct drm_connector *_connector) > intel_gmbus_force_bit(ddc, false); > } > > + /* > + * If the connector is forced on (e.g. video=HDMI-A-1:e) and the sink's > + * DDC/I2C bus is powered down during DPMS standby, keep the previously > + * cached EDID rather than wiping it and falling back to 1024x768. > + */ > + if (!drm_edid && connector->base.force && > + connector->detect_edid && connector->base.edid_blob_ptr) { > + intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref); > + return true; > + } [Severity: Medium] What happens here when a connector with a cached EDID is forced off via DRM_FORCE_OFF? Because enum drm_connector_force defines DRM_FORCE_OFF as a non-zero value, connector->base.force evaluates to true when the connector is forced off (for example via connector_write() in drivers/gpu/drm/drm_debugfs.c, which sets connector->force = DRM_FORCE_OFF without calling fill_modes() or intel_hdmi_force()). When a subsequent probe runs intel_hdmi_detect() -> intel_hdmi_set_edid(), drm_edid_read_ddc() explicitly returns NULL for DRM_FORCE_OFF: drivers/gpu/drm/drm_edid.c:drm_edid_read_ddc() { if (connector->force == DRM_FORCE_OFF) return NULL; ... } In that case, intel_hdmi_set_edid() will match !drm_edid && connector->base.force, skip intel_hdmi_unset_edid() and drm_edid_connector_update(), retain the stale detect_edid and dp_dual_mode state, and return true as if the forced-off connector were connected. The same boolean check in intel_hdmi_detect() also skips intel_hdmi_unset_edid() on Gen11+ disconnect when force is DRM_FORCE_OFF. Should these checks explicitly test for >= DRM_FORCE_ON (or != DRM_FORCE_OFF && != DRM_FORCE_UNSPECIFIED) instead of a boolean check on connector->base.force? > + > + intel_hdmi_unset_edid(&connector->base); > + > /* Below we depend on display info having been updated */ > drm_edid_connector_update(&connector->base, drm_edid); > > @@ -2609,10 +2622,11 @@ intel_hdmi_detect(struct drm_connector *_connector, bool force) > wakeref = intel_display_power_get(display, POWER_DOMAIN_GMBUS); > > if (DISPLAY_VER(display) >= 11 && > - !intel_digital_port_connected(encoder)) > + !intel_digital_port_connected(encoder)) { > + if (!connector->base.force) > + intel_hdmi_unset_edid(&connector->base); > goto out; > - > - intel_hdmi_unset_edid(&connector->base); > + } [Severity: Medium] On DISPLAY_VER(display) >= 11, if the sink drops HPD during standby so !intel_digital_port_connected(encoder) is true on a forced-on connector, could jumping to out with status = connector_status_disconnected cause CEC invalidation and hotplug churn? In intel_hdmi_detect(), jumping to out leaves status set to connector_status_disconnected: drivers/gpu/drm/i915/display/intel_hdmi.c:intel_hdmi_detect() { ... out: intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref); if (status != connector_status_connected) cec_notifier_phys_addr_invalidate(intel_hdmi->cec_notifier); return status; } First, this invalidates cec_notifier even though connector->detect_edid and display_info are kept, and subsequent calls to intel_hdmi_force() -> intel_hdmi_set_edid() while DDC is powered down return early before reaching cec_notifier_set_phys_addr(). Second, returning connector_status_disconnected while connector->base.status remains forced to connector_status_connected causes drm_helper_probe_detect_ctx() to see ret != connector->status and increment connector->epoch_counter on every probe: drivers/gpu/drm/drm_probe_helper.c:drm_helper_probe_detect_ctx() { ... if (ret != connector->status) connector->epoch_counter += 1; ... } In intel_hotplug_detect_connector(), connector->base.status is not updated when connector->base.force is set, so old_epoch_counter != connector->base.epoch_counter triggers INTEL_HOTPLUG_CHANGED and sends hotplug uevents on every HPD or poll while the sink is in standby. -- Sashiko AI review · https://sashiko.dev/#/patchset/179284522321.1666644.7085985666852699043@gmail.com?part=1 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v3] drm/i915/hdmi: preserve cached EDID on DDC failure when connector is forced 2026-10-24 12:33 ` [PATCH v2] " Aman Sharma 2026-10-24 12:47 ` sashiko-bot @ 2026-10-24 12:53 ` Aman Sharma 2026-10-27 9:31 ` Jani Nikula 1 sibling, 1 reply; 7+ messages in thread From: Aman Sharma @ 2026-10-24 12:53 UTC (permalink / raw) To: intel-gfx, dri-devel Cc: Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin, David Airlie, Simona Vetter, linux-kernel, Aman Sharma When an HDMI connector is forced enabled (e.g. via video=HDMI-A-1:e for laptop clamshell operation) and the external monitor enters DPMS standby, some monitors (such as the BenQ GW2790Q) power down their internal DDC/I2C controller, causing SCDC/EDID reads to fail with -ENXIO (-6). Currently, intel_hdmi_detect() and intel_hdmi_force() unconditionally call intel_hdmi_unset_edid() before calling intel_hdmi_set_edid(). When drm_edid_read_ddc() returns NULL during monitor standby, the connector's cached detect_edid is wiped out and drm_helper_probe_single_connector_modes() falls back to the 1024x768 VESA no-EDID mode. When the monitor wakes back up, because the connector status remained forced to connector_status_connected, no hotplug state transition occurs and the display remains stuck at 1024x768 until a manual mode probe (such as toggling the laptop lid) is triggered. Fix this by moving intel_hdmi_unset_edid() into intel_hdmi_set_edid() after checking whether a forced-on connector (DRM_FORCE_ON or DRM_FORCE_ON_DIGITAL) already has a valid cached EDID (detect_edid and edid_blob_ptr) when DDC fails, and preserving connector_status_connected on Gen11+ digital port disconnect when a forced-on connector has a cached EDID. When the monitor is awake or a different monitor is plugged in, drm_edid_read_ddc() succeeds, resets the previous EDID and dp_dual_mode state via intel_hdmi_unset_edid(), and updates the connector with the new EDID. v3: - Explicitly check for DRM_FORCE_ON / DRM_FORCE_ON_DIGITAL so DRM_FORCE_OFF still clears the cached EDID as expected. - Report connector_status_connected on Gen11+ disconnect when a forced-on connector retains its cached EDID, and jump to out in intel_hdmi_set_edid() so CEC physical address remains valid and drm_helper_probe_detect_ctx() does not increment epoch_counter on standby HPD pulses. v2: - Move intel_hdmi_unset_edid() into intel_hdmi_set_edid() so hotplug detection via intel_hdmi_detect() also preserves the cached EDID on forced connectors and resets dp_dual_mode when updating EDID. - Clear detect_edid on Gen11+ disconnect when the connector is unforced, and verify edid_blob_ptr is non-NULL before retaining detect_edid. Signed-off-by: Aman Sharma <amansharma6122002@gmail.com> --- drivers/gpu/drm/i915/display/intel_hdmi.c | 31 ++++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index b6fa1a1558b8..a14a857dfe94 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -2570,6 +2570,21 @@ intel_hdmi_set_edid(struct drm_connector *_connector) intel_gmbus_force_bit(ddc, false); } + /* + * If the connector is forced on (e.g. video=HDMI-A-1:e) and the sink's + * DDC/I2C bus is powered down during DPMS standby, keep the previously + * cached EDID rather than wiping it and falling back to 1024x768. + */ + if (!drm_edid && + (connector->base.force == DRM_FORCE_ON || + connector->base.force == DRM_FORCE_ON_DIGITAL) && + connector->detect_edid && connector->base.edid_blob_ptr) { + connected = true; + goto out; + } + + intel_hdmi_unset_edid(&connector->base); + /* Below we depend on display info having been updated */ drm_edid_connector_update(&connector->base, drm_edid); @@ -2580,6 +2595,7 @@ intel_hdmi_set_edid(struct drm_connector *_connector) connected = true; } +out: intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref); cec_notifier_set_phys_addr(intel_hdmi->cec_notifier, @@ -2611,10 +2627,15 @@ intel_hdmi_detect(struct drm_connector *_connector, bool force) wakeref = intel_display_power_get(display, POWER_DOMAIN_GMBUS); if (DISPLAY_VER(display) >= 11 && - !intel_digital_port_connected(encoder)) + !intel_digital_port_connected(encoder)) { + if ((connector->base.force == DRM_FORCE_ON || + connector->base.force == DRM_FORCE_ON_DIGITAL) && + connector->detect_edid && connector->base.edid_blob_ptr) + status = connector_status_connected; + else + intel_hdmi_unset_edid(&connector->base); goto out; - - intel_hdmi_unset_edid(&connector->base); + } if (intel_hdmi_set_edid(&connector->base)) status = connector_status_connected; @@ -2638,10 +2659,10 @@ intel_hdmi_force(struct drm_connector *_connector) if (!intel_display_driver_check_access(display)) return; - intel_hdmi_unset_edid(&connector->base); - - if (connector->base.status != connector_status_connected) + if (connector->base.status != connector_status_connected) { + intel_hdmi_unset_edid(&connector->base); return; + } intel_hdmi_set_edid(&connector->base); } -- 2.43.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v3] drm/i915/hdmi: preserve cached EDID on DDC failure when connector is forced 2026-10-24 12:53 ` [PATCH v3] " Aman Sharma @ 2026-10-27 9:31 ` Jani Nikula 0 siblings, 0 replies; 7+ messages in thread From: Jani Nikula @ 2026-10-27 9:31 UTC (permalink / raw) To: Aman Sharma, intel-gfx, dri-devel Cc: Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin, David Airlie, Simona Vetter, linux-kernel, Aman Sharma On Sat, 24 Oct 2026, Aman Sharma <amansharma6122002@gmail.com> wrote: > When an HDMI connector is forced enabled (e.g. via video=HDMI-A-1:e for > laptop clamshell operation) and the external monitor enters DPMS standby, > some monitors (such as the BenQ GW2790Q) power down their internal DDC/I2C > controller, causing SCDC/EDID reads to fail with -ENXIO (-6). > > Currently, intel_hdmi_detect() and intel_hdmi_force() unconditionally call > intel_hdmi_unset_edid() before calling intel_hdmi_set_edid(). When > drm_edid_read_ddc() returns NULL during monitor standby, the connector's > cached detect_edid is wiped out and > drm_helper_probe_single_connector_modes() falls back to the 1024x768 VESA > no-EDID mode. When the monitor wakes back up, because the connector status > remained forced to connector_status_connected, no hotplug state transition > occurs and the display remains stuck at 1024x768 until a manual mode probe > (such as toggling the laptop lid) is triggered. > > Fix this by moving intel_hdmi_unset_edid() into intel_hdmi_set_edid() after > checking whether a forced-on connector (DRM_FORCE_ON or > DRM_FORCE_ON_DIGITAL) already has a valid cached EDID (detect_edid and > edid_blob_ptr) when DDC fails, and preserving connector_status_connected > on Gen11+ digital port disconnect when a forced-on connector has a cached > EDID. When the monitor is awake or a different monitor is plugged in, > drm_edid_read_ddc() succeeds, resets the previous EDID and dp_dual_mode > state via intel_hdmi_unset_edid(), and updates the connector with the new > EDID. Connector forcing and EDID reading/caching need to remain orthogonal. The patch at hand makes a complex thing more complex. Please file a bug as described at [1], reproducing the problem. [1] https://drm.pages.freedesktop.org/intel-docs/how-to-file-i915-bugs.html > v3: > - Explicitly check for DRM_FORCE_ON / DRM_FORCE_ON_DIGITAL so DRM_FORCE_OFF > still clears the cached EDID as expected. > - Report connector_status_connected on Gen11+ disconnect when a forced-on > connector retains its cached EDID, and jump to out in > intel_hdmi_set_edid() so CEC physical address remains valid and > drm_helper_probe_detect_ctx() does not increment epoch_counter on > standby HPD pulses. > > v2: > - Move intel_hdmi_unset_edid() into intel_hdmi_set_edid() so hotplug > detection via intel_hdmi_detect() also preserves the cached EDID on > forced connectors and resets dp_dual_mode when updating EDID. > - Clear detect_edid on Gen11+ disconnect when the connector is unforced, > and verify edid_blob_ptr is non-NULL before retaining detect_edid. > > Signed-off-by: Aman Sharma <amansharma6122002@gmail.com> > --- > drivers/gpu/drm/i915/display/intel_hdmi.c | 31 ++++++++++++++++++----- > 1 file changed, 25 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c > index b6fa1a1558b8..a14a857dfe94 100644 > --- a/drivers/gpu/drm/i915/display/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c > @@ -2570,6 +2570,21 @@ intel_hdmi_set_edid(struct drm_connector *_connector) > intel_gmbus_force_bit(ddc, false); > } > > + /* > + * If the connector is forced on (e.g. video=HDMI-A-1:e) and the sink's > + * DDC/I2C bus is powered down during DPMS standby, keep the previously > + * cached EDID rather than wiping it and falling back to 1024x768. > + */ > + if (!drm_edid && > + (connector->base.force == DRM_FORCE_ON || > + connector->base.force == DRM_FORCE_ON_DIGITAL) && > + connector->detect_edid && connector->base.edid_blob_ptr) { Drivers also have no business looking at edid_blob_ptr. BR, Jani. > + connected = true; > + goto out; > + } > + > + intel_hdmi_unset_edid(&connector->base); > + > /* Below we depend on display info having been updated */ > drm_edid_connector_update(&connector->base, drm_edid); > > @@ -2580,6 +2595,7 @@ intel_hdmi_set_edid(struct drm_connector *_connector) > connected = true; > } > > +out: > intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref); > > cec_notifier_set_phys_addr(intel_hdmi->cec_notifier, > @@ -2611,10 +2627,15 @@ intel_hdmi_detect(struct drm_connector *_connector, bool force) > wakeref = intel_display_power_get(display, POWER_DOMAIN_GMBUS); > > if (DISPLAY_VER(display) >= 11 && > - !intel_digital_port_connected(encoder)) > + !intel_digital_port_connected(encoder)) { > + if ((connector->base.force == DRM_FORCE_ON || > + connector->base.force == DRM_FORCE_ON_DIGITAL) && > + connector->detect_edid && connector->base.edid_blob_ptr) > + status = connector_status_connected; > + else > + intel_hdmi_unset_edid(&connector->base); > goto out; > - > - intel_hdmi_unset_edid(&connector->base); > + } > > if (intel_hdmi_set_edid(&connector->base)) > status = connector_status_connected; > @@ -2638,10 +2659,10 @@ intel_hdmi_force(struct drm_connector *_connector) > if (!intel_display_driver_check_access(display)) > return; > > - intel_hdmi_unset_edid(&connector->base); > - > - if (connector->base.status != connector_status_connected) > + if (connector->base.status != connector_status_connected) { > + intel_hdmi_unset_edid(&connector->base); > return; > + } > > intel_hdmi_set_edid(&connector->base); > } -- Jani Nikula, Intel ^ permalink raw reply [flat|nested] 7+ messages in thread
* ✗ LGCI.VerificationFailed: failure for drm/i915/hdmi: preserve cached EDID on DDC failure when connector is forced (rev2) 2026-10-24 12:06 [PATCH] drm/i915/hdmi: preserve cached EDID on DDC failure when connector is forced Aman Sharma 2026-10-24 12:19 ` sashiko-bot 2026-10-24 12:33 ` [PATCH v2] " Aman Sharma @ 2026-10-27 15:13 ` Patchwork 2 siblings, 0 replies; 7+ messages in thread From: Patchwork @ 2026-10-27 15:13 UTC (permalink / raw) To: Aman Sharma; +Cc: intel-gfx == Series Details == Series: drm/i915/hdmi: preserve cached EDID on DDC failure when connector is forced (rev2) URL : https://patchwork.freedesktop.org/series/176942/ State : failure == Summary == Series author address 'amansharma6122002@gmail.com' is not on the allowlist, which prevents CI from being automatically triggered. If you want CI to run for this series, ask Patchwork project owners to click 'retest' on the series in Patchwork. Exception occurred during validation, bailing out! Build URL: http://gfx-ci.igk.intel.com:8080/job/CI_PW_kernel/191523/ (on built-in) ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-10-27 15:13 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-10-24 12:06 [PATCH] drm/i915/hdmi: preserve cached EDID on DDC failure when connector is forced Aman Sharma 2026-10-24 12:19 ` sashiko-bot 2026-10-24 12:33 ` [PATCH v2] " Aman Sharma 2026-10-24 12:47 ` sashiko-bot 2026-10-24 12:53 ` [PATCH v3] " Aman Sharma 2026-10-27 9:31 ` Jani Nikula 2026-10-27 15:13 ` ✗ LGCI.VerificationFailed: failure for drm/i915/hdmi: preserve cached EDID on DDC failure when connector is forced (rev2) Patchwork
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox