I found that writing to `/sys/kernel/debug/dri/*/eDP*/edid_override` wasn't working for me. I could see the new EDID take effect in `/sys/class/drm/card*-eDP*/edid` but userspace wasn't seeing it.. The problem was that panel-edp was caching the EDID that it read and using that over and over again. Let's change panel-edp to look at the EDID that's stored in the connector. This is still a cache, which is important since this function is called multiple times and readin the EDID is slow, but this property is automatically updated by drm_get_edid() (which reads the EDID) and also updated when writing the edid_override in debugfs. Fixes: 63358e24ee79 ("drm/panel: panel-simple: Cache the EDID as long as we retain power") Signed-off-by: Douglas Anderson <dianders@xxxxxxxxxxxx> --- drivers/gpu/drm/panel/panel-edp.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c index 3626469c4cc2..12241c1e32f7 100644 --- a/drivers/gpu/drm/panel/panel-edp.c +++ b/drivers/gpu/drm/panel/panel-edp.c @@ -226,8 +226,6 @@ struct panel_edp { const struct edp_panel_entry *detected_panel; - struct edid *edid; - struct drm_display_mode override_mode; enum drm_panel_orientation orientation; @@ -580,11 +578,19 @@ static int panel_edp_get_modes(struct drm_panel *panel, if (p->ddc) { pm_runtime_get_sync(panel->dev); - if (!p->edid) - p->edid = drm_get_edid(connector, p->ddc); + if (!connector->edid_blob_ptr) { + /* + * We read the EDID and then immediately free it, + * relying on the side effect of drm_get_edid() to store + * a copy in connector->edid_blob_ptr. We always use + * the copy cached in the connector since that allows + * the edid_override to work. + */ + kfree(drm_get_edid(connector, p->ddc)); + } - if (p->edid) - num += drm_add_edid_modes(connector, p->edid); + if (connector->edid_blob_ptr) + num += drm_add_edid_modes(connector, connector->edid_blob_ptr->data); pm_runtime_mark_last_busy(panel->dev); pm_runtime_put_autosuspend(panel->dev); @@ -926,9 +932,6 @@ static int panel_edp_remove(struct device *dev) if (panel->ddc && (!panel->aux || panel->ddc != &panel->aux->ddc)) put_device(&panel->ddc->dev); - kfree(panel->edid); - panel->edid = NULL; - return 0; } -- 2.37.0.170.g444d1eabd0-goog