The EDID helpers probe DDC before consulting debugfs or firmware overrides. This preserves connector-detection semantics for drivers that use a successful DDC probe as presence evidence, but it prevents drivers with independent presence detection from using an override when DDC is unresponsive.
Add an optional connector callback that replaces drm_probe_ddc() in drm_get_edid() and drm_edid_read_ddc(). Drivers can report presence using their own reliable detection while retaining the unified override and firmware EDID handling in DRM core. Signed-off-by: Mario Limonciello <[email protected]> --- Cc: Curtis Vogt <[email protected]> drivers/gpu/drm/drm_edid.c | 15 +++++++++++++-- include/drm/drm_connector.h | 17 +++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 3148038747b6e..c0e73ead308d3 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -2643,6 +2643,15 @@ drm_probe_ddc(struct i2c_adapter *adapter) } EXPORT_SYMBOL(drm_probe_ddc); +static bool drm_connector_probe_ddc(struct drm_connector *connector, + struct i2c_adapter *adapter) +{ + if (connector->funcs->probe_ddc) + return connector->funcs->probe_ddc(connector); + + return drm_probe_ddc(adapter); +} + /** * drm_get_edid - get EDID data, if available * @connector: connector we're probing @@ -2661,7 +2670,8 @@ struct edid *drm_get_edid(struct drm_connector *connector, if (connector->force == DRM_FORCE_OFF) return NULL; - if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter)) + if (connector->force == DRM_FORCE_UNSPECIFIED && + !drm_connector_probe_ddc(connector, adapter)) return NULL; edid = _drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter, NULL); @@ -2742,7 +2752,8 @@ const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector, if (connector->force == DRM_FORCE_OFF) return NULL; - if (connector->force == DRM_FORCE_UNSPECIFIED && !drm_probe_ddc(adapter)) + if (connector->force == DRM_FORCE_UNSPECIFIED && + !drm_connector_probe_ddc(connector, adapter)) return NULL; drm_edid = drm_edid_read_custom(connector, drm_do_probe_ddc_edid, adapter); diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 2ee7c59329aae..185cefe6e292f 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1640,6 +1640,23 @@ struct drm_connector_hdmi_funcs { * etc. */ struct drm_connector_funcs { + /** + * @probe_ddc: + * + * Optional connector-specific replacement for drm_probe_ddc(). Drivers + * may use this to report connector presence when they have a reliable + * detection method other than probing the DDC bus. + * + * This callback is used by drm_get_edid() and drm_edid_read_ddc() before + * retrieving an override or reading the EDID. If it is not implemented, + * the helpers fall back to drm_probe_ddc(). + * + * RETURNS: + * + * True if a sink is connected, false otherwise. + */ + bool (*probe_ddc)(struct drm_connector *connector); + /** * @dpms: * -- 2.43.0
