* [PATCH v7 00/15] drm/amd/display: more drm_edid to AMD display driver
@ 2025-11-06 16:49 Melissa Wen
2025-11-06 16:49 ` [PATCH v7 01/15] drm/amd/display: make sure drm_edid stored in aconnector doesn't leak Melissa Wen
` (14 more replies)
0 siblings, 15 replies; 23+ messages in thread
From: Melissa Wen @ 2025-11-06 16:49 UTC (permalink / raw)
To: Harry Wentland, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
airlied, alexander.deucher, andrzej.hajda, christian.koenig,
jernej.skrabec, jonas, Laurent.pinchart, maarten.lankhorst,
mripard, mwen, neil.armstrong, rfoss, simona, sunpeng.li,
tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
Hi,
We have been working on a solution to reduce the usage of drm_edid_raw
in the AMD display driver, since the current guideline in the DRM
subsystem is to stop handling raw edid data in driver-specific
implementation and use opaque `drm_edid` object with common-code
helpers.
The main change of this version is that we are now adding DM helpers for
linux-specific code with drm_edid to keep DC OS-agnostic, instead of
creating a new file and new functions, as in previous versions.
This work is an extension of [1].
- Patch 1 addresses a possible leak added by previous migration to
drm_edid.
- Patch 2 allocates a temporary drm_edid from raw edid for parsing.
- Patches 3-8 use common-code, drm_edid helpers to parse edid
capabilities instead of driver-specific solutions. For this, patch 4
introduces a new helper that gets monitor name from drm_edid.
- Patches 9-10 are groundwork to reduce the noise of Linux/DRM specific
code in the DC shared code.
- Patch 11 moves open-coded management of raw EDID data to DM helpers
with drm_edid
- Patch 12 creates a DM helper that fills dc_sink with edid data
- Patch 13 introduces a helper that compares EDIDs from two drm_edids.
- Patch 14 adds drm_edid to dc_sink struct and a DM helper to free
`drm_edid`
- Patch 15 switch dc_edid to drm_edid across the driver in a way that
the DC shared code is little affected by Linux specific stuff.
[v1] https://lore.kernel.org/dri-devel/20250411201333.151335-1-mwen@igalia.com/
Changes:
- fix broken approach to get monitor name from eld (Jani)
- I introduced a new helper that gets monitor name from drm_edid
- rename drm_edid_eq to drm_edid_eq_buf and doc fixes (Jani)
- add NULL edid checks (Jani)
- fix mishandling of product_id.manufacturer_name (Michel)
- I directly set it to manufacturer_id since sparse didn't complain.
- add Mario's r-b in the first fix patch and fix commit msg typo.
[v2] https://lore.kernel.org/dri-devel/20250507001712.120215-1-mwen@igalia.com/
Changes:
- kernel-doc and commit msg fixes (Jani)
- use drm_edid_legacy_init instead of open coded (Jani)
- place drm_edid new func into the right section (Jani)
- paramenter names fix (Jani)
- add Jani's r-b to the patch 12
- remove unnecessary include (Jani)
- call dc_edid_sink_edid_free in link_detection, instead of drm_edid_free
- rebase on top of asdn
[v3] https://lore.kernel.org/dri-devel/20250514202130.291324-1-mwen@igalia.com/
Changes:
- rebase to asdn
- some kernel-doc fixes
- move some changes to the right commit
[v4] https://lore.kernel.org/amd-gfx/20250613150015.245917-1-mwen@igalia.com/
Changes:
- fix comments and commit messages (Mario)
- remove unnecessary drm_edid dup and fix mem leak (Mario)
- add Mario's rb to patches 5-7
[v5] https://lore.kernel.org/amd-gfx/20250618152216.948406-1-mwen@igalia.com/
Changes:
- fix NULL pointer dereference (Alex H.) with the same approach proposed
by 7c3be3ce3dfae
[v6] https://lore.kernel.org/amd-gfx/20250726003816.435227-1-mwen@igalia.com/
Changes:
- use AMD DM helpers instead of new file for edid-related helpers with Linux drm_edid (Harry)
- new patch (4/15) for AMD edid_caps parsing of analog displays with a drm_edid helper.
- rebase on top of asdn
---
There are three specific points where we still use drm_edid_raw() in the
driver:
1. raw edid data for write EDID checksum in DP_TEST_EDID_CHECKSUM via
drm_dp_dpcd_write(), that AFAIK there is no common code solution yet;
2. open-coded connectivity log for dc link detection, that maybe can be
moved to drm (?);
3. open-coded parser that I suspect is a lot of duplicated code, but
needs careful examining.
I suggest to address those points in a next phase for regression control.
[1] https://lore.kernel.org/amd-gfx/20250308142650.35920-1-mwen@igalia.com/
Let me know yours thoughts!
Melissa
Melissa Wen (15):
drm/amd/display: make sure drm_edid stored in aconnector doesn't leak
drm/amd/display: start using drm_edid helpers to parse EDID caps
drm/amd/display: use drm_edid_product_id for parsing EDID product info
drm/amd/display: use drm_edid helper to set analog EDID caps
drm/edid: introduce a helper that gets monitor name from drm_edid
drm/amd/display: get panel id with drm_edid helper
drm/amd/display: get SAD from drm_eld when parsing EDID caps
drm/amd/display: get SADB from drm_eld when parsing EDID caps
drm/amd/display: simplify dm_helpers_parse_edid_caps signature
drm/amd/display: change DC functions to accept private types for edid
drm/amd/display: add DM helpers to handle EDID in DC via drm_edid
helpers
drm/amd/display: create a function to fill dc_sink with edid data
drm/edid: introduce a helper that compares edid data from two drm_edid
drm/amd/display: add drm_edid to dc_sink
drm/amd/display: move dc_sink from dc_edid to drm_edid
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 32 ++--
.../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 145 ++++++++++--------
.../display/amdgpu_dm/amdgpu_dm_mst_types.c | 21 +--
.../drm/amd/display/dc/core/dc_link_exports.c | 9 +-
drivers/gpu/drm/amd/display/dc/core/dc_sink.c | 2 +
drivers/gpu/drm/amd/display/dc/dc.h | 10 +-
drivers/gpu/drm/amd/display/dc/dm_helpers.h | 13 +-
.../gpu/drm/amd/display/dc/inc/link_service.h | 2 +-
.../drm/amd/display/dc/link/link_detection.c | 28 +---
.../drm/amd/display/dc/link/link_detection.h | 9 +-
drivers/gpu/drm/bridge/sil-sii8620.c | 2 +-
drivers/gpu/drm/display/drm_dp_mst_topology.c | 2 +-
drivers/gpu/drm/drm_edid.c | 54 +++++--
include/drm/drm_edid.h | 9 +-
14 files changed, 179 insertions(+), 159 deletions(-)
--
2.51.0
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v7 01/15] drm/amd/display: make sure drm_edid stored in aconnector doesn't leak
2025-11-06 16:49 [PATCH v7 00/15] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
@ 2025-11-06 16:49 ` Melissa Wen
2025-11-06 16:49 ` [PATCH v7 02/15] drm/amd/display: start using drm_edid helpers to parse EDID caps Melissa Wen
` (13 subsequent siblings)
14 siblings, 0 replies; 23+ messages in thread
From: Melissa Wen @ 2025-11-06 16:49 UTC (permalink / raw)
To: Harry Wentland, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
airlied, alexander.deucher, andrzej.hajda, christian.koenig,
jernej.skrabec, jonas, Laurent.pinchart, maarten.lankhorst,
mripard, mwen, neil.armstrong, rfoss, simona, sunpeng.li,
tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
Make sure the drm_edid container stored in aconnector is freed when
destroying the aconnector.
Fixes: 48edb2a4256e ("drm/amd/display: switch amdgpu_dm_connector to use struct drm_edid")
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index ba11421332da..a62f18ecd439 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7565,6 +7565,8 @@ static void amdgpu_dm_connector_destroy(struct drm_connector *connector)
dc_sink_release(aconnector->dc_sink);
aconnector->dc_sink = NULL;
+ drm_edid_free(aconnector->drm_edid);
+
drm_dp_cec_unregister_connector(&aconnector->dm_dp_aux.aux);
drm_connector_unregister(connector);
drm_connector_cleanup(connector);
--
2.51.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v7 02/15] drm/amd/display: start using drm_edid helpers to parse EDID caps
2025-11-06 16:49 [PATCH v7 00/15] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
2025-11-06 16:49 ` [PATCH v7 01/15] drm/amd/display: make sure drm_edid stored in aconnector doesn't leak Melissa Wen
@ 2025-11-06 16:49 ` Melissa Wen
2025-11-11 13:40 ` Timur Kristóf
2025-11-06 16:49 ` [PATCH v7 03/15] drm/amd/display: use drm_edid_product_id for parsing EDID product info Melissa Wen
` (12 subsequent siblings)
14 siblings, 1 reply; 23+ messages in thread
From: Melissa Wen @ 2025-11-06 16:49 UTC (permalink / raw)
To: Harry Wentland, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
airlied, alexander.deucher, andrzej.hajda, christian.koenig,
jernej.skrabec, jonas, Laurent.pinchart, maarten.lankhorst,
mripard, mwen, neil.armstrong, rfoss, simona, sunpeng.li,
tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
Groundwork that allocates a temporary drm_edid from raw edid to take
advantage of DRM common-code helpers instead of driver-specific code.
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
.../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index eb2c587b0b9b..70014bec7099 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -110,18 +110,21 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
struct drm_connector *connector = &aconnector->base;
struct drm_device *dev = connector->dev;
struct edid *edid_buf = edid ? (struct edid *) edid->raw_edid : NULL;
+ const struct drm_edid *drm_edid;
struct cea_sad *sads;
int sad_count = -1;
int sadb_count = -1;
int i = 0;
uint8_t *sadb = NULL;
-
enum dc_edid_status result = EDID_OK;
+
if (!edid_caps || !edid)
return EDID_BAD_INPUT;
- if (!drm_edid_is_valid(edid_buf))
+ drm_edid = drm_edid_alloc(edid_buf, EDID_LENGTH * (edid_buf->extensions + 1));
+
+ if (!drm_edid_valid(drm_edid))
result = EDID_BAD_CHECKSUM;
edid_caps->manufacturer_id = (uint16_t) edid_buf->mfg_id[0] |
@@ -142,8 +145,10 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
apply_edid_quirks(dev, edid_buf, edid_caps);
sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads);
- if (sad_count <= 0)
+ if (sad_count <= 0) {
+ drm_edid_free(drm_edid);
return result;
+ }
edid_caps->audio_mode_count = min(sad_count, DC_MAX_AUDIO_DESC_COUNT);
for (i = 0; i < edid_caps->audio_mode_count; ++i) {
@@ -169,6 +174,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
kfree(sads);
kfree(sadb);
+ drm_edid_free(drm_edid);
return result;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v7 03/15] drm/amd/display: use drm_edid_product_id for parsing EDID product info
2025-11-06 16:49 [PATCH v7 00/15] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
2025-11-06 16:49 ` [PATCH v7 01/15] drm/amd/display: make sure drm_edid stored in aconnector doesn't leak Melissa Wen
2025-11-06 16:49 ` [PATCH v7 02/15] drm/amd/display: start using drm_edid helpers to parse EDID caps Melissa Wen
@ 2025-11-06 16:49 ` Melissa Wen
2025-11-12 15:45 ` Mario Limonciello
2025-11-06 16:49 ` [PATCH v7 04/15] drm/amd/display: use drm_edid helper to set analog EDID caps Melissa Wen
` (11 subsequent siblings)
14 siblings, 1 reply; 23+ messages in thread
From: Melissa Wen @ 2025-11-06 16:49 UTC (permalink / raw)
To: Harry Wentland, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
airlied, alexander.deucher, andrzej.hajda, christian.koenig,
jernej.skrabec, jonas, Laurent.pinchart, maarten.lankhorst,
mripard, mwen, neil.armstrong, rfoss, simona, sunpeng.li,
tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
Use drm_edid_product_id [1] to get debug info from drm_edid instead of
directly parsing raw EDID.
[1] 3ddbd345539e ("drm/edid: add drm_edid_get_product_id()").
Signed-off-by: Melissa Wen <mwen@igalia.com>
--
v5:
- replace series url to commit hash (Mario)
---
.../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index 70014bec7099..7d05cff08233 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -111,6 +111,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
struct drm_device *dev = connector->dev;
struct edid *edid_buf = edid ? (struct edid *) edid->raw_edid : NULL;
const struct drm_edid *drm_edid;
+ struct drm_edid_product_id product_id;
struct cea_sad *sads;
int sad_count = -1;
int sadb_count = -1;
@@ -127,13 +128,13 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
if (!drm_edid_valid(drm_edid))
result = EDID_BAD_CHECKSUM;
- edid_caps->manufacturer_id = (uint16_t) edid_buf->mfg_id[0] |
- ((uint16_t) edid_buf->mfg_id[1])<<8;
- edid_caps->product_id = (uint16_t) edid_buf->prod_code[0] |
- ((uint16_t) edid_buf->prod_code[1])<<8;
- edid_caps->serial_number = edid_buf->serial;
- edid_caps->manufacture_week = edid_buf->mfg_week;
- edid_caps->manufacture_year = edid_buf->mfg_year;
+ drm_edid_get_product_id(drm_edid, &product_id);
+
+ edid_caps->manufacturer_id = product_id.manufacturer_name;
+ edid_caps->product_id = le16_to_cpu(product_id.product_code);
+ edid_caps->serial_number = le32_to_cpu(product_id.serial_number);
+ edid_caps->manufacture_week = product_id.week_of_manufacture;
+ edid_caps->manufacture_year = product_id.year_of_manufacture;
edid_caps->analog = !(edid_buf->input & DRM_EDID_INPUT_DIGITAL);
drm_edid_get_monitor_name(edid_buf,
--
2.51.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v7 04/15] drm/amd/display: use drm_edid helper to set analog EDID caps
2025-11-06 16:49 [PATCH v7 00/15] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (2 preceding siblings ...)
2025-11-06 16:49 ` [PATCH v7 03/15] drm/amd/display: use drm_edid_product_id for parsing EDID product info Melissa Wen
@ 2025-11-06 16:49 ` Melissa Wen
2025-11-11 13:38 ` Timur Kristóf
2025-11-12 15:46 ` Mario Limonciello
2025-11-06 16:49 ` [PATCH v7 05/15] drm/edid: introduce a helper that gets monitor name from drm_edid Melissa Wen
` (10 subsequent siblings)
14 siblings, 2 replies; 23+ messages in thread
From: Melissa Wen @ 2025-11-06 16:49 UTC (permalink / raw)
To: Harry Wentland, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
airlied, alexander.deucher, andrzej.hajda, christian.koenig,
jernej.skrabec, jonas, Laurent.pinchart, maarten.lankhorst,
mripard, mwen, neil.armstrong, rfoss, simona, sunpeng.li,
tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
Use drm_edid_is_digital helper instead of open-coded mask.
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index 7d05cff08233..05e5f51b0a90 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -135,7 +135,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
edid_caps->serial_number = le32_to_cpu(product_id.serial_number);
edid_caps->manufacture_week = product_id.week_of_manufacture;
edid_caps->manufacture_year = product_id.year_of_manufacture;
- edid_caps->analog = !(edid_buf->input & DRM_EDID_INPUT_DIGITAL);
+ edid_caps->analog = !drm_edid_is_digital(drm_edid);
drm_edid_get_monitor_name(edid_buf,
edid_caps->display_name,
--
2.51.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v7 05/15] drm/edid: introduce a helper that gets monitor name from drm_edid
2025-11-06 16:49 [PATCH v7 00/15] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (3 preceding siblings ...)
2025-11-06 16:49 ` [PATCH v7 04/15] drm/amd/display: use drm_edid helper to set analog EDID caps Melissa Wen
@ 2025-11-06 16:49 ` Melissa Wen
2025-11-06 16:49 ` [PATCH v7 06/15] drm/amd/display: get panel id with drm_edid helper Melissa Wen
` (9 subsequent siblings)
14 siblings, 0 replies; 23+ messages in thread
From: Melissa Wen @ 2025-11-06 16:49 UTC (permalink / raw)
To: Harry Wentland, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
airlied, alexander.deucher, andrzej.hajda, christian.koenig,
jernej.skrabec, jonas, Laurent.pinchart, maarten.lankhorst,
mripard, mwen, neil.armstrong, rfoss, simona, sunpeng.li,
tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
Original drm_edid_get_monitor_name encapsulates raw edid in drm_edid and
then call get_monitor_name. AMD still stores the display name for
debugging, but it is migrating to drm_edid, on the other hand,
drm_dp_mst_topology and sil-sii8620 still use the raw edid version.
Split drm_edid_get_monitor_name into two helpers, one that gets monitor
name from raw edid and another from drm_edid. It's temporary and the raw
edid version should be removed later.
v3:
- kernel-doc and commit msg mentionind raw edid stuff is deprecated (jani)
- use drm_edid_legacy_init instead of open coded (jani)
- move drm_edid new func declaration to its section (jani)
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
.../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 2 +-
drivers/gpu/drm/bridge/sil-sii8620.c | 2 +-
drivers/gpu/drm/display/drm_dp_mst_topology.c | 2 +-
drivers/gpu/drm/drm_edid.c | 30 +++++++++++++------
include/drm/drm_edid.h | 7 +++--
5 files changed, 29 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index 05e5f51b0a90..632cf2a32a4e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -137,7 +137,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
edid_caps->manufacture_year = product_id.year_of_manufacture;
edid_caps->analog = !drm_edid_is_digital(drm_edid);
- drm_edid_get_monitor_name(edid_buf,
+ drm_edid_get_monitor_name(drm_edid,
edid_caps->display_name,
AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS);
diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 9e48ad39e1cc..891d904a7174 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -505,7 +505,7 @@ static void sii8620_identify_sink(struct sii8620 *ctx)
else
ctx->sink_type = SINK_DVI;
- drm_edid_get_monitor_name(ctx->edid, sink_name, ARRAY_SIZE(sink_name));
+ drm_edid_raw_get_monitor_name(ctx->edid, sink_name, ARRAY_SIZE(sink_name));
dev_info(dev, "detected sink(type: %s): %s\n",
sink_str[ctx->sink_type], sink_name);
diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 64e5c176d5cc..14e916bf88d0 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -4892,7 +4892,7 @@ static void fetch_monitor_name(struct drm_dp_mst_topology_mgr *mgr,
struct edid *mst_edid;
mst_edid = drm_dp_mst_get_edid(port->connector, mgr, port);
- drm_edid_get_monitor_name(mst_edid, name, namelen);
+ drm_edid_raw_get_monitor_name(mst_edid, name, namelen);
kfree(mst_edid);
}
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index e2e85345aa9a..5ed8e683987e 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -5597,27 +5597,23 @@ static int get_monitor_name(const struct drm_edid *drm_edid, char name[13])
}
/**
- * drm_edid_get_monitor_name - fetch the monitor name from the edid
- * @edid: monitor EDID information
+ * drm_edid_get_monitor_name - fetch the monitor name from the drm_edid
+ * @drm_edid: EDID
* @name: pointer to a character array to hold the name of the monitor
* @bufsize: The size of the name buffer (should be at least 14 chars.)
*
*/
-void drm_edid_get_monitor_name(const struct edid *edid, char *name, int bufsize)
+void drm_edid_get_monitor_name(const struct drm_edid *drm_edid, char *name, int bufsize)
{
int name_length = 0;
if (bufsize <= 0)
return;
- if (edid) {
+ if (drm_edid->edid) {
char buf[13];
- struct drm_edid drm_edid = {
- .edid = edid,
- .size = edid_size(edid),
- };
- name_length = min(get_monitor_name(&drm_edid, buf), bufsize - 1);
+ name_length = min(get_monitor_name(drm_edid, buf), bufsize - 1);
memcpy(name, buf, name_length);
}
@@ -5625,6 +5621,22 @@ void drm_edid_get_monitor_name(const struct edid *edid, char *name, int bufsize)
}
EXPORT_SYMBOL(drm_edid_get_monitor_name);
+/**
+ * drm_edid_raw_get_monitor_name - fetch the monitor name from raw edid
+ * @edid: monitor EDID information
+ * @name: pointer to a character array to hold the name of the monitor
+ * @bufsize: The size of the name buffer (should be at least 14 chars.)
+ *
+ * This function is deprecated. Use drm_edid_get_monitor_name() instead.
+ */
+void drm_edid_raw_get_monitor_name(const struct edid *edid, char *name, int bufsize)
+{
+ struct drm_edid drm_edid;
+
+ drm_edid_get_monitor_name(drm_edid_legacy_init(&drm_edid, edid), name, bufsize);
+}
+EXPORT_SYMBOL(drm_edid_raw_get_monitor_name);
+
static void clear_eld(struct drm_connector *connector)
{
mutex_lock(&connector->eld_mutex);
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 3d1aecfec9b2..44ef3498a169 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -448,8 +448,8 @@ int drm_add_modes_noedid(struct drm_connector *connector,
int drm_edid_header_is_valid(const void *edid);
bool drm_edid_is_valid(struct edid *edid);
-void drm_edid_get_monitor_name(const struct edid *edid, char *name,
- int buflen);
+void drm_edid_raw_get_monitor_name(const struct edid *edid, char *name,
+ int bufsize);
struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev,
int hsize, int vsize, int fresh,
bool rb);
@@ -484,5 +484,8 @@ u32 drm_edid_get_panel_id(const struct drm_edid *drm_edid);
bool drm_edid_match(const struct drm_edid *drm_edid,
const struct drm_edid_ident *ident);
bool drm_edid_has_quirk(struct drm_connector *connector, enum drm_edid_quirk quirk);
+void drm_edid_get_monitor_name(const struct drm_edid *drm_edid,
+ char *name,
+ int bufsize);
#endif /* __DRM_EDID_H__ */
--
2.51.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v7 06/15] drm/amd/display: get panel id with drm_edid helper
2025-11-06 16:49 [PATCH v7 00/15] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (4 preceding siblings ...)
2025-11-06 16:49 ` [PATCH v7 05/15] drm/edid: introduce a helper that gets monitor name from drm_edid Melissa Wen
@ 2025-11-06 16:49 ` Melissa Wen
2025-11-11 13:46 ` Timur Kristóf
2025-11-06 16:49 ` [PATCH v7 07/15] drm/amd/display: get SAD from drm_eld when parsing EDID caps Melissa Wen
` (8 subsequent siblings)
14 siblings, 1 reply; 23+ messages in thread
From: Melissa Wen @ 2025-11-06 16:49 UTC (permalink / raw)
To: Harry Wentland, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
airlied, alexander.deucher, andrzej.hajda, christian.koenig,
jernej.skrabec, jonas, Laurent.pinchart, maarten.lankhorst,
mripard, mwen, neil.armstrong, rfoss, simona, sunpeng.li,
tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
Instead of using driver-specific code, use DRM helpers.
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
.../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index 632cf2a32a4e..c055841c3a8f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -49,16 +49,11 @@
#include "ddc_service_types.h"
#include "clk_mgr.h"
-static u32 edid_extract_panel_id(struct edid *edid)
+static void apply_edid_quirks(struct drm_device *dev,
+ const struct drm_edid *drm_edid,
+ struct dc_edid_caps *edid_caps)
{
- return (u32)edid->mfg_id[0] << 24 |
- (u32)edid->mfg_id[1] << 16 |
- (u32)EDID_PRODUCT_ID(edid);
-}
-
-static void apply_edid_quirks(struct drm_device *dev, struct edid *edid, struct dc_edid_caps *edid_caps)
-{
- uint32_t panel_id = edid_extract_panel_id(edid);
+ uint32_t panel_id = drm_edid_get_panel_id(drm_edid);
switch (panel_id) {
/* Workaround for monitors that need a delay after detecting the link */
@@ -143,7 +138,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
edid_caps->edid_hdmi = connector->display_info.is_hdmi;
- apply_edid_quirks(dev, edid_buf, edid_caps);
+ apply_edid_quirks(dev, drm_edid, edid_caps);
sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads);
if (sad_count <= 0) {
--
2.51.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v7 07/15] drm/amd/display: get SAD from drm_eld when parsing EDID caps
2025-11-06 16:49 [PATCH v7 00/15] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (5 preceding siblings ...)
2025-11-06 16:49 ` [PATCH v7 06/15] drm/amd/display: get panel id with drm_edid helper Melissa Wen
@ 2025-11-06 16:49 ` Melissa Wen
2025-11-11 13:47 ` Timur Kristóf
2025-11-06 16:49 ` [PATCH v7 08/15] drm/amd/display: get SADB " Melissa Wen
` (7 subsequent siblings)
14 siblings, 1 reply; 23+ messages in thread
From: Melissa Wen @ 2025-11-06 16:49 UTC (permalink / raw)
To: Harry Wentland, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
airlied, alexander.deucher, andrzej.hajda, christian.koenig,
jernej.skrabec, jonas, Laurent.pinchart, maarten.lankhorst,
mripard, mwen, neil.armstrong, rfoss, simona, sunpeng.li,
tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
drm_edid_connector_update() updates display info, filling ELD with audio
info from Short-Audio Descriptors in the last step of
update_dislay_info(). Our goal is stopping using raw edid, so we can
extract SAD from drm_eld instead of access raw edid to get audio caps.
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
.../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 22 ++++++++++---------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index c055841c3a8f..4333b02dc552 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -34,6 +34,7 @@
#include <drm/drm_probe_helper.h>
#include <drm/amdgpu_drm.h>
#include <drm/drm_edid.h>
+#include <drm/drm_eld.h>
#include <drm/drm_fixed.h>
#include "dm_services.h"
@@ -107,9 +108,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
struct edid *edid_buf = edid ? (struct edid *) edid->raw_edid : NULL;
const struct drm_edid *drm_edid;
struct drm_edid_product_id product_id;
- struct cea_sad *sads;
- int sad_count = -1;
- int sadb_count = -1;
+ int sad_count, sadb_count;
int i = 0;
uint8_t *sadb = NULL;
enum dc_edid_status result = EDID_OK;
@@ -123,6 +122,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
if (!drm_edid_valid(drm_edid))
result = EDID_BAD_CHECKSUM;
+ drm_edid_connector_update(connector, drm_edid);
drm_edid_get_product_id(drm_edid, &product_id);
edid_caps->manufacturer_id = product_id.manufacturer_name;
@@ -140,7 +140,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
apply_edid_quirks(dev, drm_edid, edid_caps);
- sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads);
+ sad_count = drm_eld_sad_count(connector->eld);
if (sad_count <= 0) {
drm_edid_free(drm_edid);
return result;
@@ -148,12 +148,15 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
edid_caps->audio_mode_count = min(sad_count, DC_MAX_AUDIO_DESC_COUNT);
for (i = 0; i < edid_caps->audio_mode_count; ++i) {
- struct cea_sad *sad = &sads[i];
+ struct cea_sad sad;
- edid_caps->audio_modes[i].format_code = sad->format;
- edid_caps->audio_modes[i].channel_count = sad->channels + 1;
- edid_caps->audio_modes[i].sample_rate = sad->freq;
- edid_caps->audio_modes[i].sample_size = sad->byte2;
+ if (drm_eld_sad_get(connector->eld, i, &sad) < 0)
+ continue;
+
+ edid_caps->audio_modes[i].format_code = sad.format;
+ edid_caps->audio_modes[i].channel_count = sad.channels + 1;
+ edid_caps->audio_modes[i].sample_rate = sad.freq;
+ edid_caps->audio_modes[i].sample_size = sad.byte2;
}
sadb_count = drm_edid_to_speaker_allocation((struct edid *) edid->raw_edid, &sadb);
@@ -168,7 +171,6 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
else
edid_caps->speaker_flags = DEFAULT_SPEAKER_LOCATION;
- kfree(sads);
kfree(sadb);
drm_edid_free(drm_edid);
--
2.51.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v7 08/15] drm/amd/display: get SADB from drm_eld when parsing EDID caps
2025-11-06 16:49 [PATCH v7 00/15] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (6 preceding siblings ...)
2025-11-06 16:49 ` [PATCH v7 07/15] drm/amd/display: get SAD from drm_eld when parsing EDID caps Melissa Wen
@ 2025-11-06 16:49 ` Melissa Wen
2025-11-06 16:49 ` [PATCH v7 09/15] drm/amd/display: simplify dm_helpers_parse_edid_caps signature Melissa Wen
` (6 subsequent siblings)
14 siblings, 0 replies; 23+ messages in thread
From: Melissa Wen @ 2025-11-06 16:49 UTC (permalink / raw)
To: Harry Wentland, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
airlied, alexander.deucher, andrzej.hajda, christian.koenig,
jernej.skrabec, jonas, Laurent.pinchart, maarten.lankhorst,
mripard, mwen, neil.armstrong, rfoss, simona, sunpeng.li,
tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
drm_edid_connector_update() updates display info, filling ELD with
speaker allocation data in the last step of update_dislay_info(). Our
goal is stopping using raw edid, so we can extract SADB from drm_eld
instead of access raw edid to get audio caps.
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
.../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 15 +++------------
1 file changed, 3 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index 4333b02dc552..1a38b6505465 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -108,9 +108,8 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
struct edid *edid_buf = edid ? (struct edid *) edid->raw_edid : NULL;
const struct drm_edid *drm_edid;
struct drm_edid_product_id product_id;
- int sad_count, sadb_count;
+ int sad_count;
int i = 0;
- uint8_t *sadb = NULL;
enum dc_edid_status result = EDID_OK;
@@ -159,19 +158,11 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
edid_caps->audio_modes[i].sample_size = sad.byte2;
}
- sadb_count = drm_edid_to_speaker_allocation((struct edid *) edid->raw_edid, &sadb);
-
- if (sadb_count < 0) {
- DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sadb_count);
- sadb_count = 0;
- }
-
- if (sadb_count)
- edid_caps->speaker_flags = sadb[0];
+ if (connector->eld[DRM_ELD_SPEAKER])
+ edid_caps->speaker_flags = connector->eld[DRM_ELD_SPEAKER];
else
edid_caps->speaker_flags = DEFAULT_SPEAKER_LOCATION;
- kfree(sadb);
drm_edid_free(drm_edid);
return result;
--
2.51.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v7 09/15] drm/amd/display: simplify dm_helpers_parse_edid_caps signature
2025-11-06 16:49 [PATCH v7 00/15] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (7 preceding siblings ...)
2025-11-06 16:49 ` [PATCH v7 08/15] drm/amd/display: get SADB " Melissa Wen
@ 2025-11-06 16:49 ` Melissa Wen
2025-11-06 16:49 ` [PATCH v7 10/15] drm/amd/display: change DC functions to accept private types for edid Melissa Wen
` (5 subsequent siblings)
14 siblings, 0 replies; 23+ messages in thread
From: Melissa Wen @ 2025-11-06 16:49 UTC (permalink / raw)
To: Harry Wentland, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
airlied, alexander.deucher, andrzej.hajda, christian.koenig,
jernej.skrabec, jonas, Laurent.pinchart, maarten.lankhorst,
mripard, mwen, neil.armstrong, rfoss, simona, sunpeng.li,
tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
Pass dc_sink to dm_helpers_parse_edid_caps(), since it already contains
edid info. It's a groundwork to get rid of raw edid stored as dc_edid.
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +---
.../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 23 ++++++++-----------
drivers/gpu/drm/amd/display/dc/dm_helpers.h | 7 ++----
.../drm/amd/display/dc/link/link_detection.c | 5 +---
4 files changed, 13 insertions(+), 27 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index a62f18ecd439..aaf6ffacca01 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7693,10 +7693,7 @@ static void amdgpu_dm_connector_funcs_force(struct drm_connector *connector)
memset(&dc_em_sink->edid_caps, 0, sizeof(struct dc_edid_caps));
memmove(dc_em_sink->dc_edid.raw_edid, edid,
(edid->extensions + 1) * EDID_LENGTH);
- dm_helpers_parse_edid_caps(
- dc_link,
- &dc_em_sink->dc_edid,
- &dc_em_sink->edid_caps);
+ dm_helpers_parse_edid_caps(dc_link, dc_em_sink);
}
}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index 1a38b6505465..c14d62e63c08 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -91,29 +91,27 @@ static void apply_edid_quirks(struct drm_device *dev,
/**
* dm_helpers_parse_edid_caps() - Parse edid caps
*
- * @link: current detected link
- * @edid: [in] pointer to edid
- * @edid_caps: [in] pointer to edid caps
+ * @link: current detected link (connector)
+ * @sink: current detected sink (display)
*
* Return: void
*/
-enum dc_edid_status dm_helpers_parse_edid_caps(
- struct dc_link *link,
- const struct dc_edid *edid,
- struct dc_edid_caps *edid_caps)
+enum dc_edid_status dm_helpers_parse_edid_caps(struct dc_link *link,
+ struct dc_sink *sink)
{
struct amdgpu_dm_connector *aconnector = link->priv;
struct drm_connector *connector = &aconnector->base;
struct drm_device *dev = connector->dev;
- struct edid *edid_buf = edid ? (struct edid *) edid->raw_edid : NULL;
+ struct edid *edid_buf;
const struct drm_edid *drm_edid;
struct drm_edid_product_id product_id;
+ struct dc_edid_caps *edid_caps = &sink->edid_caps;
int sad_count;
int i = 0;
enum dc_edid_status result = EDID_OK;
-
- if (!edid_caps || !edid)
+ edid_buf = (struct edid *) &sink->dc_edid.raw_edid;
+ if (!edid_caps || !edid_buf)
return EDID_BAD_INPUT;
drm_edid = drm_edid_alloc(edid_buf, EDID_LENGTH * (edid_buf->extensions + 1));
@@ -1037,10 +1035,7 @@ enum dc_edid_status dm_helpers_read_local_edid(
/* We don't need the original edid anymore */
drm_edid_free(drm_edid);
- edid_status = dm_helpers_parse_edid_caps(
- link,
- &sink->dc_edid,
- &sink->edid_caps);
+ edid_status = dm_helpers_parse_edid_caps(link, sink);
} while (edid_status == EDID_BAD_CHECKSUM && --retry > 0);
diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
index 9d160b39e8c5..ce6a70368bd0 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
@@ -59,11 +59,8 @@ void dm_helpers_free_gpu_mem(
enum dc_gpu_mem_alloc_type type,
void *pvMem);
-enum dc_edid_status dm_helpers_parse_edid_caps(
- struct dc_link *link,
- const struct dc_edid *edid,
- struct dc_edid_caps *edid_caps);
-
+enum dc_edid_status dm_helpers_parse_edid_caps(struct dc_link *link,
+ struct dc_sink *sink);
/*
* Update DP branch info
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
index 5d287874c125..c466c1404ed1 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
@@ -1575,10 +1575,7 @@ struct dc_sink *link_add_remote_sink(
dc_sink))
goto fail_add_sink;
- edid_status = dm_helpers_parse_edid_caps(
- link,
- &dc_sink->dc_edid,
- &dc_sink->edid_caps);
+ edid_status = dm_helpers_parse_edid_caps(link, dc_sink);
/*
* Treat device as no EDID device if EDID
--
2.51.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v7 10/15] drm/amd/display: change DC functions to accept private types for edid
2025-11-06 16:49 [PATCH v7 00/15] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (8 preceding siblings ...)
2025-11-06 16:49 ` [PATCH v7 09/15] drm/amd/display: simplify dm_helpers_parse_edid_caps signature Melissa Wen
@ 2025-11-06 16:49 ` Melissa Wen
2025-11-06 16:49 ` [PATCH v7 11/15] drm/amd/display: add DM helpers to handle EDID in DC via drm_edid helpers Melissa Wen
` (4 subsequent siblings)
14 siblings, 0 replies; 23+ messages in thread
From: Melissa Wen @ 2025-11-06 16:49 UTC (permalink / raw)
To: Harry Wentland, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
airlied, alexander.deucher, andrzej.hajda, christian.koenig,
jernej.skrabec, jonas, Laurent.pinchart, maarten.lankhorst,
mripard, mwen, neil.armstrong, rfoss, simona, sunpeng.li,
tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
There is an opaque obj in Linux/DRM to encapsulate edid data as
`drm_edid`. This obj isn't present in other platforms but we need to
pass it through DC when adding sink. To pass this data without
compromise the independence of DC code, make some DC functions accept
edid data as private options.
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
v7: change add_remote_sink in link_service.h too
---
drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c | 9 ++++-----
drivers/gpu/drm/amd/display/dc/dc.h | 9 ++++-----
drivers/gpu/drm/amd/display/dc/inc/link_service.h | 2 +-
drivers/gpu/drm/amd/display/dc/link/link_detection.c | 4 ++--
drivers/gpu/drm/amd/display/dc/link/link_detection.h | 9 ++++-----
5 files changed, 15 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c
index 9acd30019717..dd7a03ad8156 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c
@@ -279,11 +279,10 @@ unsigned int dc_dp_trace_get_link_loss_count(struct dc_link *link)
return link->dc->link_srv->dp_trace_get_link_loss_count(link);
}
-struct dc_sink *dc_link_add_remote_sink(
- struct dc_link *link,
- const uint8_t *edid,
- int len,
- struct dc_sink_init_data *init_data)
+struct dc_sink *dc_link_add_remote_sink(struct dc_link *link,
+ const void *edid,
+ int len,
+ struct dc_sink_init_data *init_data)
{
return link->dc->link_srv->add_remote_sink(link, edid, len, init_data);
}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 5c19df8ef641..2efb9add13ff 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -2020,11 +2020,10 @@ struct dc_sink_init_data;
* @len - size of the edid in byte
* @init_data -
*/
-struct dc_sink *dc_link_add_remote_sink(
- struct dc_link *dc_link,
- const uint8_t *edid,
- int len,
- struct dc_sink_init_data *init_data);
+struct dc_sink *dc_link_add_remote_sink(struct dc_link *dc_link,
+ const void *edid,
+ int len,
+ struct dc_sink_init_data *init_data);
/* Remove remote sink from a link with dc_connection_mst_branch connection type.
* @link - link the sink should be removed from
diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_service.h b/drivers/gpu/drm/amd/display/dc/inc/link_service.h
index 1e34e84160aa..f1a6002b0182 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/link_service.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/link_service.h
@@ -109,7 +109,7 @@ struct link_service {
enum dc_connection_type *type);
struct dc_sink *(*add_remote_sink)(
struct dc_link *link,
- const uint8_t *edid,
+ const void *edid,
int len,
struct dc_sink_init_data *init_data);
void (*remove_remote_sink)(struct dc_link *link, struct dc_sink *sink);
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
index c466c1404ed1..d2528e35ae0b 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
@@ -1540,7 +1540,7 @@ static bool link_add_remote_sink_helper(struct dc_link *dc_link, struct dc_sink
struct dc_sink *link_add_remote_sink(
struct dc_link *link,
- const uint8_t *edid,
+ const void *edid,
int len,
struct dc_sink_init_data *init_data)
{
@@ -1567,7 +1567,7 @@ struct dc_sink *link_add_remote_sink(
if (!dc_sink)
return NULL;
- memmove(dc_sink->dc_edid.raw_edid, edid, len);
+ memmove(dc_sink->dc_edid.raw_edid, (const uint8_t *) edid, len);
dc_sink->dc_edid.length = len;
if (!link_add_remote_sink_helper(
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.h b/drivers/gpu/drm/amd/display/dc/link/link_detection.h
index 1ab29476060b..d9097c1144ba 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.h
+++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.h
@@ -29,11 +29,10 @@
bool link_detect(struct dc_link *link, enum dc_detect_reason reason);
bool link_detect_connection_type(struct dc_link *link,
enum dc_connection_type *type);
-struct dc_sink *link_add_remote_sink(
- struct dc_link *link,
- const uint8_t *edid,
- int len,
- struct dc_sink_init_data *init_data);
+struct dc_sink *link_add_remote_sink(struct dc_link *link,
+ const void *edid,
+ int len,
+ struct dc_sink_init_data *init_data);
void link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink);
bool link_reset_cur_dp_mst_topology(struct dc_link *link);
const struct dc_link_status *link_get_status(const struct dc_link *link);
--
2.51.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v7 11/15] drm/amd/display: add DM helpers to handle EDID in DC via drm_edid helpers
2025-11-06 16:49 [PATCH v7 00/15] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (9 preceding siblings ...)
2025-11-06 16:49 ` [PATCH v7 10/15] drm/amd/display: change DC functions to accept private types for edid Melissa Wen
@ 2025-11-06 16:49 ` Melissa Wen
2025-11-06 16:49 ` [PATCH v7 12/15] drm/amd/display: create a function to fill dc_sink with edid data Melissa Wen
` (3 subsequent siblings)
14 siblings, 0 replies; 23+ messages in thread
From: Melissa Wen @ 2025-11-06 16:49 UTC (permalink / raw)
To: Harry Wentland, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
airlied, alexander.deucher, andrzej.hajda, christian.koenig,
jernej.skrabec, jonas, Laurent.pinchart, maarten.lankhorst,
mripard, mwen, neil.armstrong, rfoss, simona, sunpeng.li,
tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
This will allow us to remove some ocurrences of drm_edid_raw() and the
driver will reduce handling raw EDID data in favor of drm_edid helpers.
v7:
- instead of new files, move edid-related helpers to dm_helpers (Harry)
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
.../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 16 ++++++++++++++++
drivers/gpu/drm/amd/display/dc/dm_helpers.h | 4 ++++
.../gpu/drm/amd/display/dc/link/link_detection.c | 15 +--------------
3 files changed, 21 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index c14d62e63c08..f3cc6ea11c6f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -983,6 +983,22 @@ dm_helpers_read_acpi_edid(struct amdgpu_dm_connector *aconnector)
return drm_edid_read_custom(connector, dm_helpers_probe_acpi_edid, connector);
}
+bool dm_helpers_is_same_edid(struct dc_sink *prev_sink,
+ struct dc_sink *current_sink)
+{
+ struct dc_edid *old_edid = &prev_sink->dc_edid;
+ struct dc_edid *new_edid = ¤t_sink->dc_edid;
+
+ if (old_edid->length != new_edid->length)
+ return false;
+
+ if (new_edid->length == 0)
+ return false;
+
+ return (memcmp(old_edid->raw_edid,
+ new_edid->raw_edid, new_edid->length) == 0);
+}
+
enum dc_edid_status dm_helpers_read_local_edid(
struct dc_context *ctx,
struct dc_link *link,
diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
index ce6a70368bd0..2fb445933350 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
@@ -62,6 +62,10 @@ void dm_helpers_free_gpu_mem(
enum dc_edid_status dm_helpers_parse_edid_caps(struct dc_link *link,
struct dc_sink *sink);
+/* Compare two EDIDs */
+bool dm_helpers_is_same_edid(struct dc_sink *prev_sink,
+ struct dc_sink *current_sink);
+
/*
* Update DP branch info
*/
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
index d2528e35ae0b..616540acc6ee 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
@@ -622,18 +622,6 @@ static bool detect_dp(struct dc_link *link,
return true;
}
-static bool is_same_edid(struct dc_edid *old_edid, struct dc_edid *new_edid)
-{
- if (old_edid->length != new_edid->length)
- return false;
-
- if (new_edid->length == 0)
- return false;
-
- return (memcmp(old_edid->raw_edid,
- new_edid->raw_edid, new_edid->length) == 0);
-}
-
static bool wait_for_entering_dp_alt_mode(struct dc_link *link)
{
@@ -1214,8 +1202,7 @@ static bool detect_link_and_local_sink(struct dc_link *link,
// Check if edid is the same
if ((prev_sink) &&
(edid_status == EDID_THE_SAME || edid_status == EDID_OK))
- same_edid = is_same_edid(&prev_sink->dc_edid,
- &sink->dc_edid);
+ same_edid = dm_helpers_is_same_edid(prev_sink, sink);
if (sink->edid_caps.panel_patch.skip_scdc_overwrite)
link->ctx->dc->debug.hdmi20_disable = true;
--
2.51.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v7 12/15] drm/amd/display: create a function to fill dc_sink with edid data
2025-11-06 16:49 [PATCH v7 00/15] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (10 preceding siblings ...)
2025-11-06 16:49 ` [PATCH v7 11/15] drm/amd/display: add DM helpers to handle EDID in DC via drm_edid helpers Melissa Wen
@ 2025-11-06 16:49 ` Melissa Wen
2025-11-06 16:49 ` [PATCH v7 13/15] drm/edid: introduce a helper that compares edid data from two drm_edid Melissa Wen
` (2 subsequent siblings)
14 siblings, 0 replies; 23+ messages in thread
From: Melissa Wen @ 2025-11-06 16:49 UTC (permalink / raw)
To: Harry Wentland, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
airlied, alexander.deucher, andrzej.hajda, christian.koenig,
jernej.skrabec, jonas, Laurent.pinchart, maarten.lankhorst,
mripard, mwen, neil.armstrong, rfoss, simona, sunpeng.li,
tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
As part of the effort of stopping using raw edid, this commit move the
copy of the edid in DC to a dedicated function that will allow the usage
of drm_edid in the next steps.
v7:
- linux-specific func should be in dm_helpers not in a new file (Harry)
Signed-off-by: Rodrigo Siqueira <siqueira@igalia.com>
Co-developer-by: Rodrigo Siqueira <siqueira@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 8 ++++++++
drivers/gpu/drm/amd/display/dc/dm_helpers.h | 3 +++
drivers/gpu/drm/amd/display/dc/link/link_detection.c | 3 +--
3 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index f3cc6ea11c6f..a7ad93c2eb5f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -999,6 +999,14 @@ bool dm_helpers_is_same_edid(struct dc_sink *prev_sink,
new_edid->raw_edid, new_edid->length) == 0);
}
+void dm_helpers_copy_edid_to_dc(struct dc_sink *dc_sink,
+ const void *edid,
+ int len)
+{
+ memmove(dc_sink->dc_edid.raw_edid, edid, len);
+ dc_sink->dc_edid.length = len;
+}
+
enum dc_edid_status dm_helpers_read_local_edid(
struct dc_context *ctx,
struct dc_link *link,
diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
index 2fb445933350..0415cb50fe32 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
@@ -65,6 +65,9 @@ enum dc_edid_status dm_helpers_parse_edid_caps(struct dc_link *link,
/* Compare two EDIDs */
bool dm_helpers_is_same_edid(struct dc_sink *prev_sink,
struct dc_sink *current_sink);
+void dm_helpers_copy_edid_to_dc(struct dc_sink *dc_sink,
+ const void *edid, int len);
+
/*
* Update DP branch info
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
index 616540acc6ee..2ab1f28d0d19 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
@@ -1554,8 +1554,7 @@ struct dc_sink *link_add_remote_sink(
if (!dc_sink)
return NULL;
- memmove(dc_sink->dc_edid.raw_edid, (const uint8_t *) edid, len);
- dc_sink->dc_edid.length = len;
+ dm_helpers_copy_edid_to_dc(dc_sink, edid, len);
if (!link_add_remote_sink_helper(
link,
--
2.51.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v7 13/15] drm/edid: introduce a helper that compares edid data from two drm_edid
2025-11-06 16:49 [PATCH v7 00/15] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (11 preceding siblings ...)
2025-11-06 16:49 ` [PATCH v7 12/15] drm/amd/display: create a function to fill dc_sink with edid data Melissa Wen
@ 2025-11-06 16:49 ` Melissa Wen
2025-11-06 16:49 ` [PATCH v7 14/15] drm/amd/display: add drm_edid to dc_sink Melissa Wen
2025-11-06 16:49 ` [PATCH v7 15/15] drm/amd/display: move dc_sink from dc_edid to drm_edid Melissa Wen
14 siblings, 0 replies; 23+ messages in thread
From: Melissa Wen @ 2025-11-06 16:49 UTC (permalink / raw)
To: Harry Wentland, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
airlied, alexander.deucher, andrzej.hajda, christian.koenig,
jernej.skrabec, jonas, Laurent.pinchart, maarten.lankhorst,
mripard, mwen, neil.armstrong, rfoss, simona, sunpeng.li,
tzimmermann
Cc: Michel Daenzer, Jani Nikula, Jani Nikula, amd-gfx, dri-devel,
kernel-dev
AMD driver has a function used to compare if two edid are the same; this
is useful to some of the link detection algorithms implemented by
amdgpu. Since the amdgpu function can be helpful for other drivers, this
commit abstracts the AMD function to make it available at the DRM level
by wrapping existent drm_edid_eq().
v2:
- rename drm_edid_eq to drm_edid_eq_buf (jani)
- add NULL checks (jani)
v3:
- fix kernel-doc (jani)
- fix parameter names
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Co-developed-by: Rodrigo Siqueira <siqueira@igalia.com>
Signed-off-by: Rodrigo Siqueira <siqueira@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
drivers/gpu/drm/drm_edid.c | 24 +++++++++++++++++++++---
include/drm/drm_edid.h | 2 ++
2 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 5ed8e683987e..87b10f051250 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1831,8 +1831,8 @@ static bool edid_block_is_zero(const void *edid)
return mem_is_zero(edid, EDID_LENGTH);
}
-static bool drm_edid_eq(const struct drm_edid *drm_edid,
- const void *raw_edid, size_t raw_edid_size)
+static bool drm_edid_eq_buf(const struct drm_edid *drm_edid,
+ const void *raw_edid, size_t raw_edid_size)
{
bool edid1_present = drm_edid && drm_edid->edid && drm_edid->size;
bool edid2_present = raw_edid && raw_edid_size;
@@ -7001,7 +7001,7 @@ static int _drm_edid_connector_property_update(struct drm_connector *connector,
const void *old_edid = connector->edid_blob_ptr->data;
size_t old_edid_size = connector->edid_blob_ptr->length;
- if (old_edid && !drm_edid_eq(drm_edid, old_edid, old_edid_size)) {
+ if (old_edid && !drm_edid_eq_buf(drm_edid, old_edid, old_edid_size)) {
connector->epoch_counter++;
drm_dbg_kms(dev, "[CONNECTOR:%d:%s] EDID changed, epoch counter %llu\n",
connector->base.id, connector->name,
@@ -7600,3 +7600,21 @@ bool drm_edid_is_digital(const struct drm_edid *drm_edid)
drm_edid->edid->input & DRM_EDID_INPUT_DIGITAL;
}
EXPORT_SYMBOL(drm_edid_is_digital);
+
+/**
+ * drm_edid_eq - Check if EDIDs are equal
+ *
+ * @drm_edid_1: first drm_edid to compare edid
+ * @drm_edid_2: second drm_edid to compare edid
+ *
+ * Return true if EDIDs are equal.
+ */
+bool drm_edid_eq(const struct drm_edid *drm_edid_1,
+ const struct drm_edid *drm_edid_2)
+{
+ const void *edid_1 = drm_edid_1 ? drm_edid_1->edid : NULL;
+ size_t edid_1_size = drm_edid_1 ? drm_edid_1->size : 0;
+
+ return drm_edid_eq_buf(drm_edid_2, edid_1, edid_1_size);
+}
+EXPORT_SYMBOL(drm_edid_eq);
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 44ef3498a169..df15ae170fe7 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -476,6 +476,8 @@ int drm_edid_connector_update(struct drm_connector *connector,
const struct drm_edid *edid);
int drm_edid_connector_add_modes(struct drm_connector *connector);
bool drm_edid_is_digital(const struct drm_edid *drm_edid);
+bool drm_edid_eq(const struct drm_edid *drm_edid_1,
+ const struct drm_edid *drm_edid_2);
void drm_edid_get_product_id(const struct drm_edid *drm_edid,
struct drm_edid_product_id *id);
void drm_edid_print_product_id(struct drm_printer *p,
--
2.51.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v7 14/15] drm/amd/display: add drm_edid to dc_sink
2025-11-06 16:49 [PATCH v7 00/15] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (12 preceding siblings ...)
2025-11-06 16:49 ` [PATCH v7 13/15] drm/edid: introduce a helper that compares edid data from two drm_edid Melissa Wen
@ 2025-11-06 16:49 ` Melissa Wen
2025-11-11 13:44 ` Timur Kristóf
2025-11-06 16:49 ` [PATCH v7 15/15] drm/amd/display: move dc_sink from dc_edid to drm_edid Melissa Wen
14 siblings, 1 reply; 23+ messages in thread
From: Melissa Wen @ 2025-11-06 16:49 UTC (permalink / raw)
To: Harry Wentland, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
airlied, alexander.deucher, andrzej.hajda, christian.koenig,
jernej.skrabec, jonas, Laurent.pinchart, maarten.lankhorst,
mripard, mwen, neil.armstrong, rfoss, simona, sunpeng.li,
tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
Add Linux opaque object to dc_sink for storing EDID data cross driver,
drm_edid. Also include the Linux call to free this object, the
drm_edid_free()
v7:
- put new edid-related helpers in dm_helpers (Harry)
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 5 +++++
drivers/gpu/drm/amd/display/dc/core/dc_sink.c | 2 ++
drivers/gpu/drm/amd/display/dc/dc.h | 1 +
drivers/gpu/drm/amd/display/dc/dm_helpers.h | 1 +
4 files changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index a7ad93c2eb5f..419852dfc237 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -1007,6 +1007,11 @@ void dm_helpers_copy_edid_to_dc(struct dc_sink *dc_sink,
dc_sink->dc_edid.length = len;
}
+void dm_helpers_sink_edid_free(struct dc_sink *sink)
+{
+ drm_edid_free(sink->drm_edid);
+}
+
enum dc_edid_status dm_helpers_read_local_edid(
struct dc_context *ctx,
struct dc_link *link,
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_sink.c b/drivers/gpu/drm/amd/display/dc/core/dc_sink.c
index 455fa5dd1420..a5b9081879e3 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_sink.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_sink.c
@@ -65,6 +65,8 @@ void dc_sink_retain(struct dc_sink *sink)
static void dc_sink_free(struct kref *kref)
{
struct dc_sink *sink = container_of(kref, struct dc_sink, refcount);
+
+ dm_helpers_sink_edid_free(sink);
kfree(sink->dc_container_id);
kfree(sink);
}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 2efb9add13ff..3cf7507d11fa 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -2576,6 +2576,7 @@ struct scdc_caps {
struct dc_sink {
enum signal_type sink_signal;
struct dc_edid dc_edid; /* raw edid */
+ const struct drm_edid *drm_edid; /* Linux DRM EDID */
struct dc_edid_caps edid_caps; /* parse display caps */
struct dc_container_id *dc_container_id;
uint32_t dongle_max_pix_clk;
diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
index 0415cb50fe32..e23204fdd3f5 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
@@ -68,6 +68,7 @@ bool dm_helpers_is_same_edid(struct dc_sink *prev_sink,
void dm_helpers_copy_edid_to_dc(struct dc_sink *dc_sink,
const void *edid, int len);
+void dm_helpers_sink_edid_free(struct dc_sink *sink);
/*
* Update DP branch info
--
2.51.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v7 15/15] drm/amd/display: move dc_sink from dc_edid to drm_edid
2025-11-06 16:49 [PATCH v7 00/15] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (13 preceding siblings ...)
2025-11-06 16:49 ` [PATCH v7 14/15] drm/amd/display: add drm_edid to dc_sink Melissa Wen
@ 2025-11-06 16:49 ` Melissa Wen
14 siblings, 0 replies; 23+ messages in thread
From: Melissa Wen @ 2025-11-06 16:49 UTC (permalink / raw)
To: Harry Wentland, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
airlied, alexander.deucher, andrzej.hajda, christian.koenig,
jernej.skrabec, jonas, Laurent.pinchart, maarten.lankhorst,
mripard, mwen, neil.armstrong, rfoss, simona, sunpeng.li,
tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
Reduce direct handling of edid data by resorting to drm helpers that
deal with this info inside drm_edid infrastructure.
v3:
- use dc_edid_sink_edid_free in link_detection
v5:
- no need of drm_edid duplication (Mario)
- fix mem leak on dc_sink->drm_edid
v6:
- fix NULL pointer dereference (Alex H)
v7:
- rename new edid-related helpers to dm_helpers (Harry)
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 25 +++-----
.../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 62 ++++++++-----------
.../display/amdgpu_dm/amdgpu_dm_mst_types.c | 21 +++----
drivers/gpu/drm/amd/display/dc/dm_helpers.h | 2 +-
.../drm/amd/display/dc/link/link_detection.c | 3 +-
5 files changed, 46 insertions(+), 67 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index aaf6ffacca01..9e5f708a32a6 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3853,6 +3853,8 @@ void amdgpu_dm_update_connector_after_detect(
* 2. Send an event and let userspace tell us what to do
*/
if (sink) {
+ const struct drm_edid *drm_edid = sink->drm_edid;
+
/*
* TODO: check if we still need the S3 mode update workaround.
* If yes, put it here.
@@ -3864,16 +3866,15 @@ void amdgpu_dm_update_connector_after_detect(
aconnector->dc_sink = sink;
dc_sink_retain(aconnector->dc_sink);
- if (sink->dc_edid.length == 0) {
+
+ if (!drm_edid_valid(drm_edid)) {
aconnector->drm_edid = NULL;
hdmi_cec_unset_edid(aconnector);
if (aconnector->dc_link->aux_mode) {
drm_dp_cec_unset_edid(&aconnector->dm_dp_aux.aux);
}
} else {
- const struct edid *edid = (const struct edid *)sink->dc_edid.raw_edid;
-
- aconnector->drm_edid = drm_edid_alloc(edid, sink->dc_edid.length);
+ aconnector->drm_edid = drm_edid_dup(sink->drm_edid);
drm_edid_connector_update(connector, aconnector->drm_edid);
hdmi_cec_set_edid(aconnector);
@@ -7687,12 +7688,8 @@ static void amdgpu_dm_connector_funcs_force(struct drm_connector *connector)
aconnector->drm_edid = drm_edid;
/* Update emulated (virtual) sink's EDID */
if (dc_em_sink && dc_link) {
- // FIXME: Get rid of drm_edid_raw()
- const struct edid *edid = drm_edid_raw(drm_edid);
-
memset(&dc_em_sink->edid_caps, 0, sizeof(struct dc_edid_caps));
- memmove(dc_em_sink->dc_edid.raw_edid, edid,
- (edid->extensions + 1) * EDID_LENGTH);
+ dm_helpers_copy_edid_to_dc(dc_em_sink, drm_edid, 0);
dm_helpers_parse_edid_caps(dc_link, dc_em_sink);
}
}
@@ -7725,7 +7722,6 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector)
.sink_signal = SIGNAL_TYPE_VIRTUAL
};
const struct drm_edid *drm_edid;
- const struct edid *edid;
struct i2c_adapter *ddc;
if (dc_link && dc_link->aux_mode)
@@ -7745,12 +7741,9 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector)
aconnector->drm_edid = drm_edid;
- edid = drm_edid_raw(drm_edid); // FIXME: Get rid of drm_edid_raw()
- aconnector->dc_em_sink = dc_link_add_remote_sink(
- aconnector->dc_link,
- (uint8_t *)edid,
- (edid->extensions + 1) * EDID_LENGTH,
- &init_params);
+ aconnector->dc_em_sink = dc_link_add_remote_sink(aconnector->dc_link,
+ drm_edid, 0,
+ &init_params);
if (aconnector->base.force == DRM_FORCE_ON) {
aconnector->dc_sink = aconnector->dc_link->local_sink ?
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index 419852dfc237..e3f629fb604d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -102,20 +102,16 @@ enum dc_edid_status dm_helpers_parse_edid_caps(struct dc_link *link,
struct amdgpu_dm_connector *aconnector = link->priv;
struct drm_connector *connector = &aconnector->base;
struct drm_device *dev = connector->dev;
- struct edid *edid_buf;
- const struct drm_edid *drm_edid;
+ const struct drm_edid *drm_edid = sink->drm_edid;
struct drm_edid_product_id product_id;
struct dc_edid_caps *edid_caps = &sink->edid_caps;
int sad_count;
int i = 0;
enum dc_edid_status result = EDID_OK;
- edid_buf = (struct edid *) &sink->dc_edid.raw_edid;
- if (!edid_caps || !edid_buf)
+ if (!edid_caps || !drm_edid)
return EDID_BAD_INPUT;
- drm_edid = drm_edid_alloc(edid_buf, EDID_LENGTH * (edid_buf->extensions + 1));
-
if (!drm_edid_valid(drm_edid))
result = EDID_BAD_CHECKSUM;
@@ -138,10 +134,8 @@ enum dc_edid_status dm_helpers_parse_edid_caps(struct dc_link *link,
apply_edid_quirks(dev, drm_edid, edid_caps);
sad_count = drm_eld_sad_count(connector->eld);
- if (sad_count <= 0) {
- drm_edid_free(drm_edid);
+ if (sad_count <= 0)
return result;
- }
edid_caps->audio_mode_count = min(sad_count, DC_MAX_AUDIO_DESC_COUNT);
for (i = 0; i < edid_caps->audio_mode_count; ++i) {
@@ -161,8 +155,6 @@ enum dc_edid_status dm_helpers_parse_edid_caps(struct dc_link *link,
else
edid_caps->speaker_flags = DEFAULT_SPEAKER_LOCATION;
- drm_edid_free(drm_edid);
-
return result;
}
@@ -986,25 +978,31 @@ dm_helpers_read_acpi_edid(struct amdgpu_dm_connector *aconnector)
bool dm_helpers_is_same_edid(struct dc_sink *prev_sink,
struct dc_sink *current_sink)
{
- struct dc_edid *old_edid = &prev_sink->dc_edid;
- struct dc_edid *new_edid = ¤t_sink->dc_edid;
-
- if (old_edid->length != new_edid->length)
- return false;
-
- if (new_edid->length == 0)
- return false;
-
- return (memcmp(old_edid->raw_edid,
- new_edid->raw_edid, new_edid->length) == 0);
+ return drm_edid_eq(prev_sink->drm_edid, current_sink->drm_edid);
}
void dm_helpers_copy_edid_to_dc(struct dc_sink *dc_sink,
const void *edid,
int len)
{
- memmove(dc_sink->dc_edid.raw_edid, edid, len);
- dc_sink->dc_edid.length = len;
+ dc_sink->drm_edid = drm_edid_dup((const struct drm_edid *) edid);
+}
+
+void dm_helpers_copy_edid_to_sink(struct dc_sink *sink)
+{
+ const struct edid *edid;
+
+ edid = drm_edid_raw(sink->drm_edid); // FIXME: Get rid of drm_edid_raw()
+ if (!edid ||
+ edid->extensions >= sizeof(sink->dc_edid.raw_edid) / EDID_LENGTH) {
+ memset(sink->dc_edid.raw_edid, 0, sizeof(sink->dc_edid.raw_edid));
+ sink->dc_edid.length = 0;
+ return;
+ }
+
+ sink->dc_edid.length = EDID_LENGTH * (edid->extensions + 1);
+ memcpy(sink->dc_edid.raw_edid, (uint8_t *) edid,
+ sink->dc_edid.length);
}
void dm_helpers_sink_edid_free(struct dc_sink *sink)
@@ -1023,7 +1021,6 @@ enum dc_edid_status dm_helpers_read_local_edid(
int retry = 3;
enum dc_edid_status edid_status;
const struct drm_edid *drm_edid;
- const struct edid *edid;
if (link->aux_mode)
ddc = &aconnector->dm_dp_aux.aux.ddc;
@@ -1034,6 +1031,8 @@ enum dc_edid_status dm_helpers_read_local_edid(
* do check sum and retry to make sure read correct edid.
*/
do {
+ drm_edid_free(sink->drm_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);
@@ -1053,16 +1052,7 @@ enum dc_edid_status dm_helpers_read_local_edid(
if (!drm_edid)
return EDID_NO_RESPONSE;
- edid = drm_edid_raw(drm_edid); // FIXME: Get rid of drm_edid_raw()
- if (!edid ||
- edid->extensions >= sizeof(sink->dc_edid.raw_edid) / EDID_LENGTH)
- return EDID_BAD_INPUT;
-
- sink->dc_edid.length = EDID_LENGTH * (edid->extensions + 1);
- memmove(sink->dc_edid.raw_edid, (uint8_t *)edid, sink->dc_edid.length);
-
- /* We don't need the original edid anymore */
- drm_edid_free(drm_edid);
+ sink->drm_edid = drm_edid;
edid_status = dm_helpers_parse_edid_caps(link, sink);
@@ -1087,6 +1077,8 @@ enum dc_edid_status dm_helpers_read_local_edid(
test_response.bits.EDID_CHECKSUM_WRITE = 1;
+ // TODO: drm_edid doesn't have a helper for dp_write_dpcd yet
+ dm_helpers_copy_edid_to_sink(sink);
dm_helpers_dp_write_dpcd(ctx,
link,
DP_TEST_EDID_CHECKSUM,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 5e92eaa67aa3..73b8e45f8a0e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -388,12 +388,10 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
.link = aconnector->dc_link,
.sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
- dc_sink = dc_link_add_remote_sink(
- aconnector->dc_link,
- NULL,
- 0,
- &init_params);
-
+ dc_sink = dc_link_add_remote_sink(aconnector->dc_link,
+ NULL,
+ 0,
+ &init_params);
if (!dc_sink) {
DRM_ERROR("Unable to add a remote sink\n");
return 0;
@@ -426,15 +424,10 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
struct dc_sink_init_data init_params = {
.link = aconnector->dc_link,
.sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
- const struct edid *edid;
-
- edid = drm_edid_raw(aconnector->drm_edid); // FIXME: Get rid of drm_edid_raw()
- dc_sink = dc_link_add_remote_sink(
- aconnector->dc_link,
- (uint8_t *)edid,
- (edid->extensions + 1) * EDID_LENGTH,
- &init_params);
+ dc_sink = dc_link_add_remote_sink(aconnector->dc_link,
+ aconnector->drm_edid, 0,
+ &init_params);
if (!dc_sink) {
DRM_ERROR("Unable to add a remote sink\n");
return 0;
diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
index e23204fdd3f5..0e7c67af1e2d 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
@@ -67,7 +67,7 @@ bool dm_helpers_is_same_edid(struct dc_sink *prev_sink,
struct dc_sink *current_sink);
void dm_helpers_copy_edid_to_dc(struct dc_sink *dc_sink,
const void *edid, int len);
-
+void dm_helpers_copy_edid_to_sink(struct dc_sink *sink);
void dm_helpers_sink_edid_free(struct dc_sink *sink);
/*
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
index 2ab1f28d0d19..ffa98f7e9729 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
@@ -1253,6 +1253,7 @@ static bool detect_link_and_local_sink(struct dc_link *link,
dp_trace_init(link);
/* Connectivity log: detection */
+ dm_helpers_copy_edid_to_sink(sink);
for (i = 0; i < sink->dc_edid.length / DC_EDID_BLOCK_SIZE; i++) {
CONN_DATA_DETECT(link,
&sink->dc_edid.raw_edid[i * DC_EDID_BLOCK_SIZE],
@@ -1568,7 +1569,7 @@ struct dc_sink *link_add_remote_sink(
* parsing fails
*/
if (edid_status != EDID_OK && edid_status != EDID_PARTIAL_VALID) {
- dc_sink->dc_edid.length = 0;
+ dm_helpers_sink_edid_free(dc_sink);
dm_error("Bad EDID, status%d!\n", edid_status);
}
--
2.51.0
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH v7 04/15] drm/amd/display: use drm_edid helper to set analog EDID caps
2025-11-06 16:49 ` [PATCH v7 04/15] drm/amd/display: use drm_edid helper to set analog EDID caps Melissa Wen
@ 2025-11-11 13:38 ` Timur Kristóf
2025-11-12 15:46 ` Mario Limonciello
1 sibling, 0 replies; 23+ messages in thread
From: Timur Kristóf @ 2025-11-11 13:38 UTC (permalink / raw)
To: Melissa Wen, Harry Wentland, Alex Hung, Mario Limonciello,
Rodrigo Siqueira, airlied, alexander.deucher, andrzej.hajda,
christian.koenig, jernej.skrabec, jonas, Laurent.pinchart,
maarten.lankhorst, mripard, neil.armstrong, rfoss, simona,
sunpeng.li, tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
On Thu, 2025-11-06 at 13:49 -0300, Melissa Wen wrote:
> Use drm_edid_is_digital helper instead of open-coded mask.
>
> Signed-off-by: Melissa Wen <mwen@igalia.com>
Thanks for catching this, I was not aware of this helper.
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
> ---
> drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git
> a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> index 7d05cff08233..05e5f51b0a90 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> @@ -135,7 +135,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
> edid_caps->serial_number =
> le32_to_cpu(product_id.serial_number);
> edid_caps->manufacture_week =
> product_id.week_of_manufacture;
> edid_caps->manufacture_year =
> product_id.year_of_manufacture;
> - edid_caps->analog = !(edid_buf->input &
> DRM_EDID_INPUT_DIGITAL);
> + edid_caps->analog = !drm_edid_is_digital(drm_edid);
>
> drm_edid_get_monitor_name(edid_buf,
> edid_caps->display_name,
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v7 02/15] drm/amd/display: start using drm_edid helpers to parse EDID caps
2025-11-06 16:49 ` [PATCH v7 02/15] drm/amd/display: start using drm_edid helpers to parse EDID caps Melissa Wen
@ 2025-11-11 13:40 ` Timur Kristóf
0 siblings, 0 replies; 23+ messages in thread
From: Timur Kristóf @ 2025-11-11 13:40 UTC (permalink / raw)
To: Melissa Wen, Harry Wentland, Alex Hung, Mario Limonciello,
Rodrigo Siqueira, airlied, alexander.deucher, andrzej.hajda,
christian.koenig, jernej.skrabec, jonas, Laurent.pinchart,
maarten.lankhorst, mripard, neil.armstrong, rfoss, simona,
sunpeng.li, tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
On Thu, 2025-11-06 at 13:49 -0300, Melissa Wen wrote:
> Groundwork that allocates a temporary drm_edid from raw edid to take
> advantage of DRM common-code helpers instead of driver-specific code.
>
> Signed-off-by: Melissa Wen <mwen@igalia.com>
> ---
> .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 12 +++++++++-
> --
> 1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git
> a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> index eb2c587b0b9b..70014bec7099 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> @@ -110,18 +110,21 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
> struct drm_connector *connector = &aconnector->base;
> struct drm_device *dev = connector->dev;
> struct edid *edid_buf = edid ? (struct edid *) edid-
> >raw_edid : NULL;
> + const struct drm_edid *drm_edid;
> struct cea_sad *sads;
> int sad_count = -1;
> int sadb_count = -1;
> int i = 0;
> uint8_t *sadb = NULL;
> -
> enum dc_edid_status result = EDID_OK;
>
> +
> if (!edid_caps || !edid)
> return EDID_BAD_INPUT;
>
> - if (!drm_edid_is_valid(edid_buf))
> + drm_edid = drm_edid_alloc(edid_buf, EDID_LENGTH * (edid_buf-
> >extensions + 1));
> +
> + if (!drm_edid_valid(drm_edid))
> result = EDID_BAD_CHECKSUM;
>
> edid_caps->manufacturer_id = (uint16_t) edid_buf->mfg_id[0]
> |
> @@ -142,8 +145,10 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
> apply_edid_quirks(dev, edid_buf, edid_caps);
>
> sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid,
> &sads);
> - if (sad_count <= 0)
> + if (sad_count <= 0) {
> + drm_edid_free(drm_edid);
> return result;
> + }
For consistency with other parts of the codebase, I suggest adding a
label at the end of the function, above drm_edid_free. Then here you
could jump to that label.
>
> edid_caps->audio_mode_count = min(sad_count,
> DC_MAX_AUDIO_DESC_COUNT);
> for (i = 0; i < edid_caps->audio_mode_count; ++i) {
> @@ -169,6 +174,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
>
> kfree(sads);
> kfree(sadb);
> + drm_edid_free(drm_edid);
>
> return result;
> }
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v7 14/15] drm/amd/display: add drm_edid to dc_sink
2025-11-06 16:49 ` [PATCH v7 14/15] drm/amd/display: add drm_edid to dc_sink Melissa Wen
@ 2025-11-11 13:44 ` Timur Kristóf
0 siblings, 0 replies; 23+ messages in thread
From: Timur Kristóf @ 2025-11-11 13:44 UTC (permalink / raw)
To: Melissa Wen, Harry Wentland, Alex Hung, Mario Limonciello,
Rodrigo Siqueira, airlied, alexander.deucher, andrzej.hajda,
christian.koenig, jernej.skrabec, jonas, Laurent.pinchart,
maarten.lankhorst, mripard, neil.armstrong, rfoss, simona,
sunpeng.li, tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
On Thu, 2025-11-06 at 13:49 -0300, Melissa Wen wrote:
> Add Linux opaque object to dc_sink for storing EDID data cross
> driver,
> drm_edid. Also include the Linux call to free this object, the
> drm_edid_free()
>
> v7:
> - put new edid-related helpers in dm_helpers (Harry)
>
> Signed-off-by: Melissa Wen <mwen@igalia.com>
> ---
> drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 5 +++++
> drivers/gpu/drm/amd/display/dc/core/dc_sink.c | 2 ++
> drivers/gpu/drm/amd/display/dc/dc.h | 1 +
> drivers/gpu/drm/amd/display/dc/dm_helpers.h | 1 +
> 4 files changed, 9 insertions(+)
>
> diff --git
> a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> index a7ad93c2eb5f..419852dfc237 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> @@ -1007,6 +1007,11 @@ void dm_helpers_copy_edid_to_dc(struct dc_sink
> *dc_sink,
> dc_sink->dc_edid.length = len;
> }
>
> +void dm_helpers_sink_edid_free(struct dc_sink *sink)
> +{
> + drm_edid_free(sink->drm_edid);
> +}
> +
> enum dc_edid_status dm_helpers_read_local_edid(
> struct dc_context *ctx,
> struct dc_link *link,
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_sink.c
> b/drivers/gpu/drm/amd/display/dc/core/dc_sink.c
> index 455fa5dd1420..a5b9081879e3 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_sink.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_sink.c
> @@ -65,6 +65,8 @@ void dc_sink_retain(struct dc_sink *sink)
> static void dc_sink_free(struct kref *kref)
> {
> struct dc_sink *sink = container_of(kref, struct dc_sink,
> refcount);
> +
> + dm_helpers_sink_edid_free(sink);
> kfree(sink->dc_container_id);
> kfree(sink);
> }
> diff --git a/drivers/gpu/drm/amd/display/dc/dc.h
> b/drivers/gpu/drm/amd/display/dc/dc.h
> index 2efb9add13ff..3cf7507d11fa 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc.h
> @@ -2576,6 +2576,7 @@ struct scdc_caps {
> struct dc_sink {
> enum signal_type sink_signal;
> struct dc_edid dc_edid; /* raw edid */
> + const struct drm_edid *drm_edid; /* Linux DRM EDID */
If we want DC to be platform-agnostic, I don't think we should use
pointers to DRM structures here. I am not an expert, but I assume that
DC needs an EDID on other platforms as well.
How about something like this?
const void *platform_edid; /* Pointer to platform specific EDID struct */
Then, on Linux this can be the drm_edid and on other platforms
it can be an equivalent struct.
> struct dc_edid_caps edid_caps; /* parse display caps */
> struct dc_container_id *dc_container_id;
> uint32_t dongle_max_pix_clk;
> diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h
> b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
> index 0415cb50fe32..e23204fdd3f5 100644
> --- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h
> +++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
> @@ -68,6 +68,7 @@ bool dm_helpers_is_same_edid(struct dc_sink
> *prev_sink,
> void dm_helpers_copy_edid_to_dc(struct dc_sink *dc_sink,
> const void *edid, int len);
>
> +void dm_helpers_sink_edid_free(struct dc_sink *sink);
>
> /*
> * Update DP branch info
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v7 06/15] drm/amd/display: get panel id with drm_edid helper
2025-11-06 16:49 ` [PATCH v7 06/15] drm/amd/display: get panel id with drm_edid helper Melissa Wen
@ 2025-11-11 13:46 ` Timur Kristóf
0 siblings, 0 replies; 23+ messages in thread
From: Timur Kristóf @ 2025-11-11 13:46 UTC (permalink / raw)
To: Melissa Wen, Harry Wentland, Alex Hung, Mario Limonciello,
Rodrigo Siqueira, airlied, alexander.deucher, andrzej.hajda,
christian.koenig, jernej.skrabec, jonas, Laurent.pinchart,
maarten.lankhorst, mripard, neil.armstrong, rfoss, simona,
sunpeng.li, tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
On Thu, 2025-11-06 at 13:49 -0300, Melissa Wen wrote:
> Instead of using driver-specific code, use DRM helpers.
>
> Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
> Signed-off-by: Melissa Wen <mwen@igalia.com>
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
> ---
> .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 15 +++++--------
> --
> 1 file changed, 5 insertions(+), 10 deletions(-)
>
> diff --git
> a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> index 632cf2a32a4e..c055841c3a8f 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> @@ -49,16 +49,11 @@
> #include "ddc_service_types.h"
> #include "clk_mgr.h"
>
> -static u32 edid_extract_panel_id(struct edid *edid)
> +static void apply_edid_quirks(struct drm_device *dev,
> + const struct drm_edid *drm_edid,
> + struct dc_edid_caps *edid_caps)
> {
> - return (u32)edid->mfg_id[0] << 24 |
> - (u32)edid->mfg_id[1] << 16 |
> - (u32)EDID_PRODUCT_ID(edid);
> -}
> -
> -static void apply_edid_quirks(struct drm_device *dev, struct edid
> *edid, struct dc_edid_caps *edid_caps)
> -{
> - uint32_t panel_id = edid_extract_panel_id(edid);
> + uint32_t panel_id = drm_edid_get_panel_id(drm_edid);
>
> switch (panel_id) {
> /* Workaround for monitors that need a delay after detecting
> the link */
> @@ -143,7 +138,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
>
> edid_caps->edid_hdmi = connector->display_info.is_hdmi;
>
> - apply_edid_quirks(dev, edid_buf, edid_caps);
> + apply_edid_quirks(dev, drm_edid, edid_caps);
>
> sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid,
> &sads);
> if (sad_count <= 0) {
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v7 07/15] drm/amd/display: get SAD from drm_eld when parsing EDID caps
2025-11-06 16:49 ` [PATCH v7 07/15] drm/amd/display: get SAD from drm_eld when parsing EDID caps Melissa Wen
@ 2025-11-11 13:47 ` Timur Kristóf
0 siblings, 0 replies; 23+ messages in thread
From: Timur Kristóf @ 2025-11-11 13:47 UTC (permalink / raw)
To: Melissa Wen, Harry Wentland, Alex Hung, Mario Limonciello,
Rodrigo Siqueira, airlied, alexander.deucher, andrzej.hajda,
christian.koenig, jernej.skrabec, jonas, Laurent.pinchart,
maarten.lankhorst, mripard, neil.armstrong, rfoss, simona,
sunpeng.li, tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
On Thu, 2025-11-06 at 13:49 -0300, Melissa Wen wrote:
> drm_edid_connector_update() updates display info, filling ELD with
> audio
> info from Short-Audio Descriptors in the last step of
> update_dislay_info(). Our goal is stopping using raw edid, so we can
> extract SAD from drm_eld instead of access raw edid to get audio
> caps.
>
> Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
> Signed-off-by: Melissa Wen <mwen@igalia.com>
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
> ---
> .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 22 ++++++++++-------
> --
> 1 file changed, 12 insertions(+), 10 deletions(-)
>
> diff --git
> a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> index c055841c3a8f..4333b02dc552 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> @@ -34,6 +34,7 @@
> #include <drm/drm_probe_helper.h>
> #include <drm/amdgpu_drm.h>
> #include <drm/drm_edid.h>
> +#include <drm/drm_eld.h>
> #include <drm/drm_fixed.h>
>
> #include "dm_services.h"
> @@ -107,9 +108,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
> struct edid *edid_buf = edid ? (struct edid *) edid-
> >raw_edid : NULL;
> const struct drm_edid *drm_edid;
> struct drm_edid_product_id product_id;
> - struct cea_sad *sads;
> - int sad_count = -1;
> - int sadb_count = -1;
> + int sad_count, sadb_count;
> int i = 0;
> uint8_t *sadb = NULL;
> enum dc_edid_status result = EDID_OK;
> @@ -123,6 +122,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
> if (!drm_edid_valid(drm_edid))
> result = EDID_BAD_CHECKSUM;
>
> + drm_edid_connector_update(connector, drm_edid);
> drm_edid_get_product_id(drm_edid, &product_id);
>
> edid_caps->manufacturer_id = product_id.manufacturer_name;
> @@ -140,7 +140,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
>
> apply_edid_quirks(dev, drm_edid, edid_caps);
>
> - sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid,
> &sads);
> + sad_count = drm_eld_sad_count(connector->eld);
> if (sad_count <= 0) {
> drm_edid_free(drm_edid);
> return result;
> @@ -148,12 +148,15 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
>
> edid_caps->audio_mode_count = min(sad_count,
> DC_MAX_AUDIO_DESC_COUNT);
> for (i = 0; i < edid_caps->audio_mode_count; ++i) {
> - struct cea_sad *sad = &sads[i];
> + struct cea_sad sad;
>
> - edid_caps->audio_modes[i].format_code = sad->format;
> - edid_caps->audio_modes[i].channel_count = sad-
> >channels + 1;
> - edid_caps->audio_modes[i].sample_rate = sad->freq;
> - edid_caps->audio_modes[i].sample_size = sad->byte2;
> + if (drm_eld_sad_get(connector->eld, i, &sad) < 0)
> + continue;
> +
> + edid_caps->audio_modes[i].format_code = sad.format;
> + edid_caps->audio_modes[i].channel_count =
> sad.channels + 1;
> + edid_caps->audio_modes[i].sample_rate = sad.freq;
> + edid_caps->audio_modes[i].sample_size = sad.byte2;
> }
>
> sadb_count = drm_edid_to_speaker_allocation((struct edid *)
> edid->raw_edid, &sadb);
> @@ -168,7 +171,6 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
> else
> edid_caps->speaker_flags = DEFAULT_SPEAKER_LOCATION;
>
> - kfree(sads);
> kfree(sadb);
> drm_edid_free(drm_edid);
>
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v7 03/15] drm/amd/display: use drm_edid_product_id for parsing EDID product info
2025-11-06 16:49 ` [PATCH v7 03/15] drm/amd/display: use drm_edid_product_id for parsing EDID product info Melissa Wen
@ 2025-11-12 15:45 ` Mario Limonciello
0 siblings, 0 replies; 23+ messages in thread
From: Mario Limonciello @ 2025-11-12 15:45 UTC (permalink / raw)
To: Melissa Wen, Harry Wentland, Alex Hung, Rodrigo Siqueira, airlied,
alexander.deucher, andrzej.hajda, christian.koenig,
jernej.skrabec, jonas, Laurent.pinchart, maarten.lankhorst,
mripard, neil.armstrong, rfoss, simona, sunpeng.li, tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
On 11/6/25 10:49 AM, Melissa Wen wrote:
> Use drm_edid_product_id [1] to get debug info from drm_edid instead of
> directly parsing raw EDID.
>
> [1] 3ddbd345539e ("drm/edid: add drm_edid_get_product_id()").
Correct syntax is commit XXXXXXXXX ("description"). IE something like this:
commit 3ddbd345539e ("drm/edid: add drm_edid_get_product_id()")
introduced drm_edid_product_id. Use this to get debug info from
drm_edid instead of directly parsing the raw EDID.
>
> Signed-off-by: Melissa Wen <mwen@igalia.com>
> --
>
> v5:
> - replace series url to commit hash (Mario)
> ---
> .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 15 ++++++++-------
> 1 file changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> index 70014bec7099..7d05cff08233 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> @@ -111,6 +111,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
> struct drm_device *dev = connector->dev;
> struct edid *edid_buf = edid ? (struct edid *) edid->raw_edid : NULL;
> const struct drm_edid *drm_edid;
> + struct drm_edid_product_id product_id;
> struct cea_sad *sads;
> int sad_count = -1;
> int sadb_count = -1;
> @@ -127,13 +128,13 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
> if (!drm_edid_valid(drm_edid))
> result = EDID_BAD_CHECKSUM;
>
> - edid_caps->manufacturer_id = (uint16_t) edid_buf->mfg_id[0] |
> - ((uint16_t) edid_buf->mfg_id[1])<<8;
> - edid_caps->product_id = (uint16_t) edid_buf->prod_code[0] |
> - ((uint16_t) edid_buf->prod_code[1])<<8;
> - edid_caps->serial_number = edid_buf->serial;
> - edid_caps->manufacture_week = edid_buf->mfg_week;
> - edid_caps->manufacture_year = edid_buf->mfg_year;
> + drm_edid_get_product_id(drm_edid, &product_id);
> +
> + edid_caps->manufacturer_id = product_id.manufacturer_name;
> + edid_caps->product_id = le16_to_cpu(product_id.product_code);
> + edid_caps->serial_number = le32_to_cpu(product_id.serial_number);
> + edid_caps->manufacture_week = product_id.week_of_manufacture;
> + edid_caps->manufacture_year = product_id.year_of_manufacture;
> edid_caps->analog = !(edid_buf->input & DRM_EDID_INPUT_DIGITAL);
>
> drm_edid_get_monitor_name(edid_buf,
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v7 04/15] drm/amd/display: use drm_edid helper to set analog EDID caps
2025-11-06 16:49 ` [PATCH v7 04/15] drm/amd/display: use drm_edid helper to set analog EDID caps Melissa Wen
2025-11-11 13:38 ` Timur Kristóf
@ 2025-11-12 15:46 ` Mario Limonciello
1 sibling, 0 replies; 23+ messages in thread
From: Mario Limonciello @ 2025-11-12 15:46 UTC (permalink / raw)
To: Melissa Wen, Harry Wentland, Alex Hung, Rodrigo Siqueira, airlied,
alexander.deucher, andrzej.hajda, christian.koenig,
jernej.skrabec, jonas, Laurent.pinchart, maarten.lankhorst,
mripard, neil.armstrong, rfoss, simona, sunpeng.li, tzimmermann
Cc: Michel Daenzer, Jani Nikula, amd-gfx, dri-devel, kernel-dev
On 11/6/25 10:49 AM, Melissa Wen wrote:
> Use drm_edid_is_digital helper instead of open-coded mask.
>
> Signed-off-by: Melissa Wen <mwen@igalia.com>
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
> ---
> drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> index 7d05cff08233..05e5f51b0a90 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> @@ -135,7 +135,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
> edid_caps->serial_number = le32_to_cpu(product_id.serial_number);
> edid_caps->manufacture_week = product_id.week_of_manufacture;
> edid_caps->manufacture_year = product_id.year_of_manufacture;
> - edid_caps->analog = !(edid_buf->input & DRM_EDID_INPUT_DIGITAL);
> + edid_caps->analog = !drm_edid_is_digital(drm_edid);
>
> drm_edid_get_monitor_name(edid_buf,
> edid_caps->display_name,
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2025-11-12 15:46 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-06 16:49 [PATCH v7 00/15] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
2025-11-06 16:49 ` [PATCH v7 01/15] drm/amd/display: make sure drm_edid stored in aconnector doesn't leak Melissa Wen
2025-11-06 16:49 ` [PATCH v7 02/15] drm/amd/display: start using drm_edid helpers to parse EDID caps Melissa Wen
2025-11-11 13:40 ` Timur Kristóf
2025-11-06 16:49 ` [PATCH v7 03/15] drm/amd/display: use drm_edid_product_id for parsing EDID product info Melissa Wen
2025-11-12 15:45 ` Mario Limonciello
2025-11-06 16:49 ` [PATCH v7 04/15] drm/amd/display: use drm_edid helper to set analog EDID caps Melissa Wen
2025-11-11 13:38 ` Timur Kristóf
2025-11-12 15:46 ` Mario Limonciello
2025-11-06 16:49 ` [PATCH v7 05/15] drm/edid: introduce a helper that gets monitor name from drm_edid Melissa Wen
2025-11-06 16:49 ` [PATCH v7 06/15] drm/amd/display: get panel id with drm_edid helper Melissa Wen
2025-11-11 13:46 ` Timur Kristóf
2025-11-06 16:49 ` [PATCH v7 07/15] drm/amd/display: get SAD from drm_eld when parsing EDID caps Melissa Wen
2025-11-11 13:47 ` Timur Kristóf
2025-11-06 16:49 ` [PATCH v7 08/15] drm/amd/display: get SADB " Melissa Wen
2025-11-06 16:49 ` [PATCH v7 09/15] drm/amd/display: simplify dm_helpers_parse_edid_caps signature Melissa Wen
2025-11-06 16:49 ` [PATCH v7 10/15] drm/amd/display: change DC functions to accept private types for edid Melissa Wen
2025-11-06 16:49 ` [PATCH v7 11/15] drm/amd/display: add DM helpers to handle EDID in DC via drm_edid helpers Melissa Wen
2025-11-06 16:49 ` [PATCH v7 12/15] drm/amd/display: create a function to fill dc_sink with edid data Melissa Wen
2025-11-06 16:49 ` [PATCH v7 13/15] drm/edid: introduce a helper that compares edid data from two drm_edid Melissa Wen
2025-11-06 16:49 ` [PATCH v7 14/15] drm/amd/display: add drm_edid to dc_sink Melissa Wen
2025-11-11 13:44 ` Timur Kristóf
2025-11-06 16:49 ` [PATCH v7 15/15] drm/amd/display: move dc_sink from dc_edid to drm_edid Melissa Wen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox