The existing EDID read helpers retain a DDC presence probe before they
consult debugfs or firmware overrides. This is necessary for drivers that
use a successful EDID read as connector-presence evidence.

Drivers with independent presence detection cannot retrieve an override
when DDC is unresponsive.

Add drm_edid_read_override() so those drivers can retrieve a configured
override without probing hardware. Keep DRM_FORCE_OFF semantics and the
existing debugfs-before-firmware priority.

Signed-off-by: Mario Limonciello <[email protected]>
---
 drivers/gpu/drm/drm_edid.c | 22 ++++++++++++++++++++++
 include/drm/drm_edid.h     |  1 +
 2 files changed, 23 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 3148038747b6e..4857bcae5e117 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2289,6 +2289,28 @@ static const struct drm_edid 
*drm_edid_override_get(struct drm_connector *connec
        return IS_ERR(override) ? NULL : override;
 }
 
+/**
+ * drm_edid_read_override - read override or firmware EDID
+ * @connector: connector to use
+ *
+ * Read the EDID from debugfs override_edid or firmware EDID
+ * (drm_edid_load_firmware() and drm.edid_firmware parameter), in this priority
+ * order. This does not probe the connector or read the EDID from hardware.
+ *
+ * The returned pointer must be freed using drm_edid_free().
+ *
+ * Return: Pointer to EDID, or NULL if the connector is forced off or no EDID
+ * override is available.
+ */
+const struct drm_edid *drm_edid_read_override(struct drm_connector *connector)
+{
+       if (connector->force == DRM_FORCE_OFF)
+               return NULL;
+
+       return drm_edid_override_get(connector);
+}
+EXPORT_SYMBOL(drm_edid_read_override);
+
 /* For debugfs edid_override implementation */
 int drm_edid_override_show(struct drm_connector *connector, struct seq_file *m)
 {
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index a2617aa34edfc..cdd874b98340d 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -469,6 +469,7 @@ const struct drm_edid *drm_edid_dup(const struct drm_edid 
*drm_edid);
 void drm_edid_free(const struct drm_edid *drm_edid);
 bool drm_edid_valid(const struct drm_edid *drm_edid);
 const struct edid *drm_edid_raw(const struct drm_edid *drm_edid);
+const struct drm_edid *drm_edid_read_override(struct drm_connector *connector);
 const struct drm_edid *drm_edid_read(struct drm_connector *connector);
 const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
                                         struct i2c_adapter *adapter);
-- 
2.43.0

Reply via email to