]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amd/display: Use EDID from VBIOS embedded panel info
authorTimur Kristóf <timur.kristof@gmail.com>
Tue, 28 Apr 2026 11:40:45 +0000 (13:40 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 29 Apr 2026 14:41:46 +0000 (10:41 -0400)
When an embedded panel has no DDC, read the EDID from
the VBIOS embedded panel info and use that.

Fixes: 7c7f5b15be65 ("drm/amd/display: Refactor edid read.")
Link: https://gitlab.freedesktop.org/drm/amd/-/work_items/5192
Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 399b9abc353c62f6e37d38325edbdb6c2c00411c)

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c

index 3b8ae7798a937271db2cb606baf606d3c7c5a737..a3cb05490dc9165d304b210cc7f70eefb20cb3ae 100644 (file)
@@ -1032,6 +1032,45 @@ dm_helpers_read_acpi_edid(struct amdgpu_dm_connector *aconnector)
        return drm_edid_read_custom(connector, dm_helpers_probe_acpi_edid, connector);
 }
 
+static const struct drm_edid *
+dm_helpers_read_vbios_hardcoded_edid(struct dc_link *link, struct amdgpu_dm_connector *aconnector)
+{
+       struct dc_bios *bios = link->ctx->dc_bios;
+       struct embedded_panel_info info;
+       const struct drm_edid *edid;
+       enum bp_result r;
+
+       if (!dc_is_embedded_signal(link->connector_signal) ||
+           !bios->funcs->get_embedded_panel_info)
+               return NULL;
+
+       memset(&info, 0, sizeof(info));
+       r = bios->funcs->get_embedded_panel_info(bios, &info);
+
+       if (r != BP_RESULT_OK) {
+               dm_error("Error when reading embedded panel info: %u\n", r);
+               return NULL;
+       }
+
+       if (!info.fake_edid || !info.fake_edid_size) {
+               dm_error("Embedded panel info doesn't contain an EDID\n");
+               return NULL;
+       }
+
+       edid = drm_edid_alloc(info.fake_edid, info.fake_edid_size);
+
+       if (!drm_edid_valid(edid)) {
+               dm_error("EDID from embedded panel info is invalid\n");
+               drm_edid_free(edid);
+               return NULL;
+       }
+
+       aconnector->base.display_info.width_mm = info.panel_width_mm;
+       aconnector->base.display_info.height_mm = info.panel_height_mm;
+
+       return edid;
+}
+
 void populate_hdmi_info_from_connector(struct drm_hdmi_info *hdmi, struct dc_edid_caps *edid_caps)
 {
        edid_caps->scdc_present = hdmi->scdc.supported;
@@ -1052,6 +1091,9 @@ enum dc_edid_status dm_helpers_read_local_edid(
 
        if (link->aux_mode)
                ddc = &aconnector->dm_dp_aux.aux.ddc;
+       else if (link->ddc_hw_inst == GPIO_DDC_LINE_UNKNOWN &&
+                dc_is_embedded_signal(link->connector_signal))
+               ddc = NULL;
        else
                ddc = &aconnector->i2c->base;
 
@@ -1065,6 +1107,8 @@ enum dc_edid_status dm_helpers_read_local_edid(
                drm_edid = dm_helpers_read_acpi_edid(aconnector);
                if (drm_edid)
                        drm_info(connector->dev, "Using ACPI provided EDID for %s\n", connector->name);
+               else if (!ddc)
+                       drm_edid = dm_helpers_read_vbios_hardcoded_edid(link, aconnector);
                else
                        drm_edid = drm_edid_read_ddc(connector, ddc);
                drm_edid_connector_update(connector, drm_edid);