On Sun, 31 May 2026, Jens Glathe via B4 Relay <[email protected]> wrote: > From: Jens Glathe <[email protected]> > > drm_edid_read_ddc() can return a structurally valid EDID from which > drm_edid_connector_add_modes() still returns zero modes. This triggers > the error:
What are the EDID contents in that case? Where does it originate from? A valid but "not what you wanted" EDID doesn't show up from thin air. Perhaps it's the hub/adapter replying with some placeholder EDID instead of the actual sink EDID. Maybe it's the timing and/or ordering. Feels like root causing would be in order before adding hacks like this that are notoriously difficult to remove in the future, and will easily block future progress. BR, Jani. > > [drm:msm_dp_bridge_get_modes [msm]] *ERROR* failed to get DP sink > modes, rc=0 > > even though the link is ready. Since the EDID is only read once, this > error persists and the display comes up with 640x480 resolution. > > Add a retry of drm_edid_read_ddc() inside get_modes() when the initial > read produces no usable modes. The bad EDID is freed before retrying > and container_of ensures access to the DDC channel. This directly > addresses the observed "valid but empty/garbage" EDID case on > flaky DP plugs and adapters. > > I tested this on a few of my "flaky" type-c to HDMI adapters and hubs, > getting no "retry failed" messages and the desired resolution. Without > the patch most plugs would result in 640x480 external display. > > Fixes: [5bea90ad9743d2] "drm/msm/dp: switch to struct drm_edid" > > Signed-off-by: Jens Glathe <[email protected]> > --- > drivers/gpu/drm/msm/dp/dp_panel.c | 28 ++++++++++++++++++++++++++++ > 1 file changed, 28 insertions(+) > > diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c > b/drivers/gpu/drm/msm/dp/dp_panel.c > index 6bb021820d7c5..4f27c8129b0ef 100644 > --- a/drivers/gpu/drm/msm/dp/dp_panel.c > +++ b/drivers/gpu/drm/msm/dp/dp_panel.c > @@ -327,11 +327,39 @@ u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel > *msm_dp_panel, > int msm_dp_panel_get_modes(struct msm_dp_panel *msm_dp_panel, > struct drm_connector *connector) > { > + int modes; > + int retry; > + struct msm_dp_panel_private *panel; > + > if (!msm_dp_panel) { > DRM_ERROR("invalid input\n"); > return -EINVAL; > } > > + panel = container_of(msm_dp_panel, struct msm_dp_panel_private, > msm_dp_panel); > + > + if (msm_dp_panel->drm_edid) { > + modes = drm_edid_connector_add_modes(connector); > + if (modes > 0) > + return modes; > + > + drm_edid_free(msm_dp_panel->drm_edid); > + msm_dp_panel->drm_edid = NULL; > + } > + > + for (retry = 0; retry < 5; retry++) { > + usleep_range(20000, 25000); > + msm_dp_panel->drm_edid = > + drm_edid_read_ddc(connector, &panel->aux->ddc); > + if (msm_dp_panel->drm_edid) > + break; > + > + drm_dbg_dp(connector->dev, > + "get_modes re-read attempt %d/5 failed\n", > + retry + 1); > + } > + > + drm_edid_connector_update(connector, msm_dp_panel->drm_edid); > if (msm_dp_panel->drm_edid) > return drm_edid_connector_add_modes(connector); > > > --- > base-commit: 7da7f07112610a520567421dd2ffcb51beaefbcc > change-id: 20260531-drm_plug_flaky_edid-cc7743f6f909 > > Best regards, -- Jani Nikula, Intel
