* [PATCH v2 00/14] drm/amd/display: more drm_edid to AMD display driver
@ 2025-05-07 0:03 Melissa Wen
2025-05-07 0:03 ` [PATCH v2 01/14] drm/amd/display: make sure drm_edid stored in aconnector doesn't leak Melissa Wen
` (13 more replies)
0 siblings, 14 replies; 21+ messages in thread
From: Melissa Wen @ 2025-05-07 0:03 UTC (permalink / raw)
To: airlied, alexander.deucher, alex.hung, andrzej.hajda,
christian.koenig, harry.wentland, maarten.lankhorst,
mario.limonciello, mripard, mwen, neil.armstrong, rfoss, simona,
siqueira, sunpeng.li, tzimmermann
Cc: Jani Nikula, amd-gfx, Michel Daenzer, dri-devel, kernel-dev
Hi,
Siqueira and I 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.
In short, this series approaches the issue of maintaining DC as an
OS-agnostic component by creating a mid layer to isolate `drm_edid`
helpers that need to be called in the DC code, while allowing other OSes
to implement their specific implementation. This 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-7 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 8-9 are groundwork to reduce the noise of Linux/DRM specific
code in the DC shared code
- Patch 10 creates a mid layer to make DC embraces different ways of
handling EDID by platforms.
- Patch 11 move open-coded management of raw EDID data to the mid
layer created before.
- Patch 12 introduces a helper that compares EDIDs from two drm_edids.
- Patch 13 adds drm_edid to dc_sink struct and a mid-layer helper to
free `drm_edid`.
- Patch 14 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.
---
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 (12):
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/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/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
Rodrigo Siqueira (2):
drm/amd/display: add a mid-layer file to handle EDID in DC
drm/amd/display: create a function to fill dc_sink with edid data
.../gpu/drm/amd/display/amdgpu_dm/Makefile | 1 +
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 33 +++----
.../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 97 ++++++++-----------
.../display/amdgpu_dm/amdgpu_dm_mst_types.c | 21 ++--
.../gpu/drm/amd/display/amdgpu_dm/dc_edid.c | 34 +++++++
.../gpu/drm/amd/display/amdgpu_dm/dc_edid.h | 15 +++
.../drm/amd/display/dc/core/dc_link_exports.c | 9 +-
drivers/gpu/drm/amd/display/dc/core/dc_sink.c | 3 +
drivers/gpu/drm/amd/display/dc/dc.h | 12 ++-
drivers/gpu/drm/amd/display/dc/dm_helpers.h | 7 +-
drivers/gpu/drm/amd/display/dc/inc/link.h | 9 +-
.../drm/amd/display/dc/link/link_detection.c | 30 ++----
.../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 | 57 ++++++++---
include/drm/drm_edid.h | 9 +-
17 files changed, 195 insertions(+), 155 deletions(-)
create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c
create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h
--
2.47.2
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v2 01/14] drm/amd/display: make sure drm_edid stored in aconnector doesn't leak
2025-05-07 0:03 [PATCH v2 00/14] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
@ 2025-05-07 0:03 ` Melissa Wen
2025-05-07 0:03 ` [PATCH v2 02/14] drm/amd/display: start using drm_edid helpers to parse EDID caps Melissa Wen
` (12 subsequent siblings)
13 siblings, 0 replies; 21+ messages in thread
From: Melissa Wen @ 2025-05-07 0:03 UTC (permalink / raw)
To: harry.wentland, sunpeng.li, alexander.deucher, christian.koenig,
airlied, simona, mario.limonciello, alex.hung, mwen, siqueira
Cc: Jani Nikula, amd-gfx, Michel Daenzer, dri-devel, kernel-dev
Make sure the drm_edid container stored in aconnector is freed when
destroying the aconnector.
Fixes: 48edb2a4 ("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 8984e211dd1c..ba975071c066 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7396,6 +7396,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.47.2
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 02/14] drm/amd/display: start using drm_edid helpers to parse EDID caps
2025-05-07 0:03 [PATCH v2 00/14] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
2025-05-07 0:03 ` [PATCH v2 01/14] drm/amd/display: make sure drm_edid stored in aconnector doesn't leak Melissa Wen
@ 2025-05-07 0:03 ` Melissa Wen
2025-05-07 0:03 ` [PATCH v2 03/14] drm/amd/display: use drm_edid_product_id for parsing EDID product info Melissa Wen
` (11 subsequent siblings)
13 siblings, 0 replies; 21+ messages in thread
From: Melissa Wen @ 2025-05-07 0:03 UTC (permalink / raw)
To: harry.wentland, sunpeng.li, alexander.deucher, christian.koenig,
airlied, simona
Cc: Jani Nikula, amd-gfx, Alex Hung, Mario Limonciello,
Rodrigo Siqueira, Michel Daenzer, 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 d4395b92fb85..5543780f1024 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,18 +108,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] |
@@ -139,8 +142,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) {
@@ -166,6 +171,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
kfree(sads);
kfree(sadb);
+ drm_edid_free(drm_edid);
return result;
}
--
2.47.2
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 03/14] drm/amd/display: use drm_edid_product_id for parsing EDID product info
2025-05-07 0:03 [PATCH v2 00/14] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
2025-05-07 0:03 ` [PATCH v2 01/14] drm/amd/display: make sure drm_edid stored in aconnector doesn't leak Melissa Wen
2025-05-07 0:03 ` [PATCH v2 02/14] drm/amd/display: start using drm_edid helpers to parse EDID caps Melissa Wen
@ 2025-05-07 0:03 ` Melissa Wen
2025-05-07 0:03 ` [PATCH v2 04/14] drm/edid: introduce a helper that gets monitor name from drm_edid Melissa Wen
` (10 subsequent siblings)
13 siblings, 0 replies; 21+ messages in thread
From: Melissa Wen @ 2025-05-07 0:03 UTC (permalink / raw)
To: harry.wentland, sunpeng.li, alexander.deucher, christian.koenig,
airlied, simona
Cc: Jani Nikula, amd-gfx, Alex Hung, Mario Limonciello,
Rodrigo Siqueira, Michel Daenzer, dri-devel, kernel-dev
Since [1], we can use drm_edid_product_id to get debug info from
drm_edid instead of directly parsing EDID.
Link: https://lore.kernel.org/dri-devel/cover.1712655867.git.jani.nikula@intel.com/ [1]
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
.../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 5543780f1024..b1085f1195f7 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
@@ -109,6 +109,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;
@@ -125,13 +126,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;
drm_edid_get_monitor_name(edid_buf,
edid_caps->display_name,
--
2.47.2
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 04/14] drm/edid: introduce a helper that gets monitor name from drm_edid
2025-05-07 0:03 [PATCH v2 00/14] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (2 preceding siblings ...)
2025-05-07 0:03 ` [PATCH v2 03/14] drm/amd/display: use drm_edid_product_id for parsing EDID product info Melissa Wen
@ 2025-05-07 0:03 ` Melissa Wen
2025-05-08 11:39 ` Jani Nikula
2025-05-07 0:03 ` [PATCH v2 05/14] drm/amd/display: get panel id with drm_edid helper Melissa Wen
` (9 subsequent siblings)
13 siblings, 1 reply; 21+ messages in thread
From: Melissa Wen @ 2025-05-07 0:03 UTC (permalink / raw)
To: harry.wentland, sunpeng.li, alexander.deucher, christian.koenig,
airlied, simona, andrzej.hajda, neil.armstrong, rfoss,
maarten.lankhorst, mripard, tzimmermann
Cc: Jani Nikula, amd-gfx, Alex Hung, Mario Limonciello,
Rodrigo Siqueira, Michel Daenzer, 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.
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 | 33 ++++++++++++++-----
include/drm/drm_edid.h | 7 ++--
5 files changed, 32 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 b1085f1195f7..514da4d5d300 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
@@ -134,7 +134,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
edid_caps->manufacture_week = product_id.week_of_manufacture;
edid_caps->manufacture_year = product_id.year_of_manufacture;
- 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 28a2e1ee04b2..c2d60b9c28fd 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 3a1f1ffc7b55..b17a602516ee 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -4896,7 +4896,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 13bc4c290b17..6e4cffd467f1 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -5575,27 +5575,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);
}
@@ -5603,6 +5599,25 @@ 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.)
+ *
+ */
+void drm_edid_raw_get_monitor_name(const struct edid *edid, char *name, int bufsize)
+{
+ struct drm_edid drm_edid = {
+ .edid = edid,
+ .size = edid ? edid_size(edid) : 0,
+ };
+
+ drm_edid_get_monitor_name(&drm_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 eaac5e665892..ceb522c4f4c2 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -441,8 +441,11 @@ 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_get_monitor_name(const struct drm_edid *drm_edid,
+ char *name,
+ int bufsize);
+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);
--
2.47.2
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 05/14] drm/amd/display: get panel id with drm_edid helper
2025-05-07 0:03 [PATCH v2 00/14] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (3 preceding siblings ...)
2025-05-07 0:03 ` [PATCH v2 04/14] drm/edid: introduce a helper that gets monitor name from drm_edid Melissa Wen
@ 2025-05-07 0:03 ` Melissa Wen
2025-05-07 0:04 ` [PATCH v2 06/14] drm/amd/display: get SAD from drm_eld when parsing EDID caps Melissa Wen
` (8 subsequent siblings)
13 siblings, 0 replies; 21+ messages in thread
From: Melissa Wen @ 2025-05-07 0:03 UTC (permalink / raw)
To: harry.wentland, sunpeng.li, alexander.deucher, christian.koenig,
airlied, simona
Cc: Jani Nikula, amd-gfx, Alex Hung, Mario Limonciello,
Rodrigo Siqueira, Michel Daenzer, dri-devel, kernel-dev
Instead of using driver-specific code, use DRM helpers.
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 514da4d5d300..760da13612b9 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
@@ -48,16 +48,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 */
@@ -140,7 +135,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.47.2
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 06/14] drm/amd/display: get SAD from drm_eld when parsing EDID caps
2025-05-07 0:03 [PATCH v2 00/14] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (4 preceding siblings ...)
2025-05-07 0:03 ` [PATCH v2 05/14] drm/amd/display: get panel id with drm_edid helper Melissa Wen
@ 2025-05-07 0:04 ` Melissa Wen
2025-05-07 0:04 ` [PATCH v2 07/14] drm/amd/display: get SADB " Melissa Wen
` (7 subsequent siblings)
13 siblings, 0 replies; 21+ messages in thread
From: Melissa Wen @ 2025-05-07 0:04 UTC (permalink / raw)
To: harry.wentland, sunpeng.li, alexander.deucher, christian.koenig,
airlied, simona
Cc: Jani Nikula, amd-gfx, Alex Hung, Mario Limonciello,
Rodrigo Siqueira, Michel Daenzer, 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.
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 760da13612b9..10af9db47c39 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
@@ -33,6 +33,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"
@@ -105,9 +106,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;
@@ -121,6 +120,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;
@@ -137,7 +137,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;
@@ -145,12 +145,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);
@@ -165,7 +168,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.47.2
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 07/14] drm/amd/display: get SADB from drm_eld when parsing EDID caps
2025-05-07 0:03 [PATCH v2 00/14] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (5 preceding siblings ...)
2025-05-07 0:04 ` [PATCH v2 06/14] drm/amd/display: get SAD from drm_eld when parsing EDID caps Melissa Wen
@ 2025-05-07 0:04 ` Melissa Wen
2025-05-07 0:04 ` [PATCH v2 08/14] drm/amd/display: simplify dm_helpers_parse_edid_caps signature Melissa Wen
` (6 subsequent siblings)
13 siblings, 0 replies; 21+ messages in thread
From: Melissa Wen @ 2025-05-07 0:04 UTC (permalink / raw)
To: harry.wentland, sunpeng.li, alexander.deucher, christian.koenig,
airlied, simona
Cc: Jani Nikula, amd-gfx, Alex Hung, Mario Limonciello,
Rodrigo Siqueira, Michel Daenzer, 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.
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 10af9db47c39..e7cfbee6c67f 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
@@ -106,9 +106,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;
@@ -156,19 +155,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.47.2
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 08/14] drm/amd/display: simplify dm_helpers_parse_edid_caps signature
2025-05-07 0:03 [PATCH v2 00/14] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (6 preceding siblings ...)
2025-05-07 0:04 ` [PATCH v2 07/14] drm/amd/display: get SADB " Melissa Wen
@ 2025-05-07 0:04 ` Melissa Wen
2025-05-07 0:04 ` [PATCH v2 09/14] drm/amd/display: change DC functions to accept private types for edid Melissa Wen
` (5 subsequent siblings)
13 siblings, 0 replies; 21+ messages in thread
From: Melissa Wen @ 2025-05-07 0:04 UTC (permalink / raw)
To: harry.wentland, sunpeng.li, alexander.deucher, christian.koenig,
airlied, simona
Cc: Jani Nikula, amd-gfx, Alex Hung, Mario Limonciello,
Rodrigo Siqueira, Michel Daenzer, 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 | 18 +++++++-----------
drivers/gpu/drm/amd/display/dc/dm_helpers.h | 7 ++-----
.../drm/amd/display/dc/link/link_detection.c | 5 +----
4 files changed, 11 insertions(+), 24 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 ba975071c066..c98904155481 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7528,10 +7528,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 e7cfbee6c67f..6e42b610cdea 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
@@ -95,23 +95,22 @@ static void apply_edid_quirks(struct drm_device *dev,
*
* 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));
@@ -1030,10 +1029,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 cc9191a5c9e6..8c7a00c1ad2b 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
@@ -1429,10 +1429,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.47.2
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 09/14] drm/amd/display: change DC functions to accept private types for edid
2025-05-07 0:03 [PATCH v2 00/14] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (7 preceding siblings ...)
2025-05-07 0:04 ` [PATCH v2 08/14] drm/amd/display: simplify dm_helpers_parse_edid_caps signature Melissa Wen
@ 2025-05-07 0:04 ` Melissa Wen
2025-05-07 0:04 ` [PATCH v2 10/14] drm/amd/display: add a mid-layer file to handle EDID in DC Melissa Wen
` (4 subsequent siblings)
13 siblings, 0 replies; 21+ messages in thread
From: Melissa Wen @ 2025-05-07 0:04 UTC (permalink / raw)
To: harry.wentland, sunpeng.li, alexander.deucher, christian.koenig,
airlied, simona
Cc: Jani Nikula, amd-gfx, Alex Hung, Mario Limonciello,
Rodrigo Siqueira, Michel Daenzer, 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>
---
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.h | 9 ++++-----
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, 18 insertions(+), 22 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 71e15da4bb69..b6f03ac16cad 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
@@ -278,11 +278,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 2230e36c4f12..c93e074ea736 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1878,11 +1878,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.h b/drivers/gpu/drm/amd/display/dc/inc/link.h
index 2948a696ee12..ab69af34ec82 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/link.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/link.h
@@ -107,11 +107,10 @@ struct link_service {
bool (*detect_link)(struct dc_link *link, enum dc_detect_reason reason);
bool (*detect_connection_type)(struct dc_link *link,
enum dc_connection_type *type);
- struct dc_sink *(*add_remote_sink)(
- struct dc_link *link,
- const uint8_t *edid,
- int len,
- struct dc_sink_init_data *init_data);
+ struct dc_sink *(*add_remote_sink)(struct dc_link *link,
+ const void *edid,
+ int len,
+ struct dc_sink_init_data *init_data);
void (*remove_remote_sink)(struct dc_link *link, struct dc_sink *sink);
bool (*get_hpd_state)(struct dc_link *link);
struct gpio *(*get_hpd_gpio)(struct dc_bios *dcb,
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 8c7a00c1ad2b..6d05ddb194c9 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
@@ -1394,7 +1394,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)
{
@@ -1421,7 +1421,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 7da05078721e..9cd3aa36c7d8 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.47.2
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 10/14] drm/amd/display: add a mid-layer file to handle EDID in DC
2025-05-07 0:03 [PATCH v2 00/14] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (8 preceding siblings ...)
2025-05-07 0:04 ` [PATCH v2 09/14] drm/amd/display: change DC functions to accept private types for edid Melissa Wen
@ 2025-05-07 0:04 ` Melissa Wen
2025-05-07 0:04 ` [PATCH v2 11/14] drm/amd/display: create a function to fill dc_sink with edid data Melissa Wen
` (3 subsequent siblings)
13 siblings, 0 replies; 21+ messages in thread
From: Melissa Wen @ 2025-05-07 0:04 UTC (permalink / raw)
To: harry.wentland, sunpeng.li, alexander.deucher, christian.koenig,
airlied, simona
Cc: Jani Nikula, amd-gfx, Alex Hung, Mario Limonciello,
Rodrigo Siqueira, Michel Daenzer, dri-devel, kernel-dev
From: Rodrigo Siqueira <siqueira@igalia.com>
Since DC is a shared code, this commit introduces a new file to work as
a mid-layer in DC for the edid manipulation.
Signed-off-by: Rodrigo Siqueira <siqueira@igalia.com>
Co-developed-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
.../gpu/drm/amd/display/amdgpu_dm/Makefile | 1 +
.../gpu/drm/amd/display/amdgpu_dm/dc_edid.c | 19 +++++++++++++++++++
.../gpu/drm/amd/display/amdgpu_dm/dc_edid.h | 11 +++++++++++
.../drm/amd/display/dc/link/link_detection.c | 17 +++--------------
4 files changed, 34 insertions(+), 14 deletions(-)
create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c
create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
index ab2a97e354da..30188bf75724 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
@@ -38,6 +38,7 @@ AMDGPUDM = \
amdgpu_dm_pp_smu.o \
amdgpu_dm_psr.o \
amdgpu_dm_replay.o \
+ dc_edid.o \
amdgpu_dm_wb.o
ifdef CONFIG_DRM_AMD_DC_FP
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c
new file mode 100644
index 000000000000..fab873b091f5
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: MIT
+#include "amdgpu_dm/dc_edid.h"
+#include "dc.h"
+
+bool dc_edid_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);
+}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h
new file mode 100644
index 000000000000..7e3b1177bc8a
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: MIT */
+
+#ifndef __DC_EDID_H__
+#define __DC_EDID_H__
+
+#include "dc.h"
+
+bool dc_edid_is_same_edid(struct dc_sink *prev_sink,
+ struct dc_sink *current_sink);
+
+#endif /* __DC_EDID_H__ */
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 6d05ddb194c9..e748721f31e4 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
@@ -48,6 +48,8 @@
#include "dm_helpers.h"
#include "clk_mgr.h"
+#include "dc_edid.h"
+
// Offset DPCD 050Eh == 0x5A
#define MST_HUB_ID_0x5A 0x5A
@@ -616,18 +618,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)
{
@@ -1114,8 +1104,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 = dc_edid_is_same_edid(prev_sink, sink);
if (sink->edid_caps.panel_patch.skip_scdc_overwrite)
link->ctx->dc->debug.hdmi20_disable = true;
--
2.47.2
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 11/14] drm/amd/display: create a function to fill dc_sink with edid data
2025-05-07 0:03 [PATCH v2 00/14] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (9 preceding siblings ...)
2025-05-07 0:04 ` [PATCH v2 10/14] drm/amd/display: add a mid-layer file to handle EDID in DC Melissa Wen
@ 2025-05-07 0:04 ` Melissa Wen
2025-05-08 11:41 ` Jani Nikula
2025-05-07 0:04 ` [PATCH v2 12/14] drm/edid: introduce a helper that compares edid data from two drm_edid Melissa Wen
` (2 subsequent siblings)
13 siblings, 1 reply; 21+ messages in thread
From: Melissa Wen @ 2025-05-07 0:04 UTC (permalink / raw)
To: harry.wentland, sunpeng.li, alexander.deucher, christian.koenig,
airlied, simona
Cc: Jani Nikula, amd-gfx, Alex Hung, Mario Limonciello,
Rodrigo Siqueira, Michel Daenzer, dri-devel, kernel-dev
From: Rodrigo Siqueira <siqueira@igalia.com>
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.
Signed-off-by: Rodrigo Siqueira <siqueira@igalia.com>
Co-developer--by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c | 8 ++++++++
drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h | 2 ++
drivers/gpu/drm/amd/display/dc/link/link_detection.c | 3 +--
3 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c
index fab873b091f5..39fcaa16a14a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c
@@ -17,3 +17,11 @@ bool dc_edid_is_same_edid(struct dc_sink *prev_sink,
return (memcmp(old_edid->raw_edid,
new_edid->raw_edid, new_edid->length) == 0);
}
+
+void dc_edid_copy_edid_to_dc(struct dc_sink *dc_sink,
+ const void *edid,
+ int len)
+{
+ memmove(dc_sink->dc_edid.raw_edid, (const uint8_t *) edid, len);
+ dc_sink->dc_edid.length = len;
+}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h
index 7e3b1177bc8a..f42cd5bbc730 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h
@@ -7,5 +7,7 @@
bool dc_edid_is_same_edid(struct dc_sink *prev_sink,
struct dc_sink *current_sink);
+void dc_edid_copy_edid_to_dc(struct dc_sink *dc_sink,
+ const void *edid, int len);
#endif /* __DC_EDID_H__ */
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 e748721f31e4..978d2b4a4d29 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
@@ -1410,8 +1410,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;
+ dc_edid_copy_edid_to_dc(dc_sink, edid, len);
if (!link_add_remote_sink_helper(
link,
--
2.47.2
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 12/14] drm/edid: introduce a helper that compares edid data from two drm_edid
2025-05-07 0:03 [PATCH v2 00/14] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (10 preceding siblings ...)
2025-05-07 0:04 ` [PATCH v2 11/14] drm/amd/display: create a function to fill dc_sink with edid data Melissa Wen
@ 2025-05-07 0:04 ` Melissa Wen
2025-05-08 11:47 ` Jani Nikula
2025-05-07 0:04 ` [PATCH v2 13/14] drm/amd/display: add drm_edid to dc_sink Melissa Wen
2025-05-07 0:04 ` [PATCH v2 14/14] drm/amd/display: move dc_sink from dc_edid to drm_edid Melissa Wen
13 siblings, 1 reply; 21+ messages in thread
From: Melissa Wen @ 2025-05-07 0:04 UTC (permalink / raw)
To: maarten.lankhorst, mripard, tzimmermann, airlied, simona
Cc: Jani Nikula, amd-gfx, Alex Hung, Mario Limonciello,
Rodrigo Siqueira, Michel Daenzer, 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)
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 6e4cffd467f1..079042ccbc41 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1820,8 +1820,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;
@@ -6918,7 +6918,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,
@@ -7523,3 +7523,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_edid_eq - Check if EDIDs are equal
+ *
+ * @drm_edid_old: old drm_edid to compare edid
+ * @drm_edid_new: new 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 ceb522c4f4c2..c0e49c4a32e9 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -472,6 +472,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_first,
+ const struct drm_edid *drm_edid_second);
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.47.2
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 13/14] drm/amd/display: add drm_edid to dc_sink
2025-05-07 0:03 [PATCH v2 00/14] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (11 preceding siblings ...)
2025-05-07 0:04 ` [PATCH v2 12/14] drm/edid: introduce a helper that compares edid data from two drm_edid Melissa Wen
@ 2025-05-07 0:04 ` Melissa Wen
2025-05-08 11:50 ` Jani Nikula
2025-05-07 0:04 ` [PATCH v2 14/14] drm/amd/display: move dc_sink from dc_edid to drm_edid Melissa Wen
13 siblings, 1 reply; 21+ messages in thread
From: Melissa Wen @ 2025-05-07 0:04 UTC (permalink / raw)
To: harry.wentland, sunpeng.li, alexander.deucher, christian.koenig,
airlied, simona
Cc: Jani Nikula, amd-gfx, Alex Hung, Mario Limonciello,
Rodrigo Siqueira, Michel Daenzer, 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()
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c | 7 +++++++
drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h | 1 +
drivers/gpu/drm/amd/display/dc/core/dc_sink.c | 3 +++
drivers/gpu/drm/amd/display/dc/dc.h | 3 +++
4 files changed, 14 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c
index 39fcaa16a14a..fa0f0e61f05d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
#include "amdgpu_dm/dc_edid.h"
#include "dc.h"
+#include <drm/drm_edid.h>
bool dc_edid_is_same_edid(struct dc_sink *prev_sink,
struct dc_sink *current_sink)
@@ -25,3 +26,9 @@ void dc_edid_copy_edid_to_dc(struct dc_sink *dc_sink,
memmove(dc_sink->dc_edid.raw_edid, (const uint8_t *) edid, len);
dc_sink->dc_edid.length = len;
}
+
+
+void dc_edid_sink_edid_free(struct dc_sink *sink)
+{
+ drm_edid_free(sink->drm_edid);
+}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h
index f42cd5bbc730..2c76768be459 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h
@@ -9,5 +9,6 @@ bool dc_edid_is_same_edid(struct dc_sink *prev_sink,
struct dc_sink *current_sink);
void dc_edid_copy_edid_to_dc(struct dc_sink *dc_sink,
const void *edid, int len);
+void dc_edid_sink_edid_free(struct dc_sink *sink);
#endif /* __DC_EDID_H__ */
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..3774a3245506 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_sink.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_sink.c
@@ -26,6 +26,7 @@
#include "dm_services.h"
#include "dm_helpers.h"
#include "core_types.h"
+#include "dc_edid.h"
/*******************************************************************************
* Private functions
@@ -65,6 +66,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);
+
+ dc_edid_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 c93e074ea736..54f6ed33e373 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -46,6 +46,8 @@
#include "dmub/inc/dmub_cmd.h"
+#include <drm/drm_edid.h>
+
struct abm_save_restore;
/* forward declaration */
@@ -2433,6 +2435,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;
--
2.47.2
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 14/14] drm/amd/display: move dc_sink from dc_edid to drm_edid
2025-05-07 0:03 [PATCH v2 00/14] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
` (12 preceding siblings ...)
2025-05-07 0:04 ` [PATCH v2 13/14] drm/amd/display: add drm_edid to dc_sink Melissa Wen
@ 2025-05-07 0:04 ` Melissa Wen
13 siblings, 0 replies; 21+ messages in thread
From: Melissa Wen @ 2025-05-07 0:04 UTC (permalink / raw)
To: harry.wentland, sunpeng.li, alexander.deucher, christian.koenig,
airlied, simona
Cc: Jani Nikula, amd-gfx, Alex Hung, Mario Limonciello,
Rodrigo Siqueira, Michel Daenzer, dri-devel, kernel-dev
Reduce direct handling of edid data by resorting to drm helpers that
deal with this info inside drm_edid infrastructure.
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 26 +++++++------------
.../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 24 +++++------------
.../display/amdgpu_dm/amdgpu_dm_mst_types.c | 21 +++++----------
.../gpu/drm/amd/display/amdgpu_dm/dc_edid.c | 26 +++++++++----------
.../gpu/drm/amd/display/amdgpu_dm/dc_edid.h | 1 +
.../drm/amd/display/dc/link/link_detection.c | 3 ++-
6 files changed, 40 insertions(+), 61 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 c98904155481..2b440e59b771 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -68,6 +68,7 @@
#endif
#include "amdgpu_dm_psr.h"
#include "amdgpu_dm_replay.h"
+#include "dc_edid.h"
#include "ivsrcid/ivsrcid_vislands30.h"
@@ -3857,6 +3858,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.
@@ -3868,16 +3871,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);
@@ -7522,12 +7524,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);
+ dc_edid_copy_edid_to_dc(dc_em_sink, drm_edid, 0);
dm_helpers_parse_edid_caps(dc_link, dc_em_sink);
}
}
@@ -7560,7 +7558,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)
@@ -7580,12 +7577,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 6e42b610cdea..9d2ea7e75bfb 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
@@ -48,6 +48,7 @@
#include "dm_helpers.h"
#include "ddc_service_types.h"
#include "clk_mgr.h"
+#include "dc_edid.h"
static void apply_edid_quirks(struct drm_device *dev,
const struct drm_edid *drm_edid,
@@ -101,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;
@@ -136,10 +133,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) {
@@ -159,8 +154,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;
}
@@ -992,7 +985,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;
@@ -1022,11 +1014,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()
- 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 */
+ sink->drm_edid = drm_edid_dup(drm_edid);
drm_edid_free(drm_edid);
edid_status = dm_helpers_parse_edid_caps(link, sink);
@@ -1052,6 +1040,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
+ dc_edid_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 d19aea595722..6b19361f8445 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
@@ -353,12 +353,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;
@@ -391,15 +389,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/amdgpu_dm/dc_edid.c b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c
index fa0f0e61f05d..b25fe4afbd85 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c
@@ -6,25 +6,25 @@
bool dc_edid_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 dc_edid_copy_edid_to_dc(struct dc_sink *dc_sink,
const void *edid,
int len)
{
- memmove(dc_sink->dc_edid.raw_edid, (const uint8_t *) edid, len);
- dc_sink->dc_edid.length = len;
+ dc_sink->drm_edid = drm_edid_dup((const struct drm_edid *) edid);
+}
+
+void dc_edid_copy_edid_to_sink(struct dc_sink *sink)
+{
+ const struct edid *edid;
+ uint32_t edid_length;
+
+ edid = drm_edid_raw(sink->drm_edid); // FIXME: Get rid of drm_edid_raw()
+ edid_length = EDID_LENGTH * (edid->extensions + 1);
+ memcpy(sink->dc_edid.raw_edid, (uint8_t *) edid, edid_length);
+ sink->dc_edid.length = edid_length;
}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h
index 2c76768be459..a95cc6ccc743 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h
@@ -9,6 +9,7 @@ bool dc_edid_is_same_edid(struct dc_sink *prev_sink,
struct dc_sink *current_sink);
void dc_edid_copy_edid_to_dc(struct dc_sink *dc_sink,
const void *edid, int len);
+void dc_edid_copy_edid_to_sink(struct dc_sink *sink);
void dc_edid_sink_edid_free(struct dc_sink *sink);
#endif /* __DC_EDID_H__ */
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 978d2b4a4d29..40cf1f0aa7cf 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
@@ -1142,6 +1142,7 @@ static bool detect_link_and_local_sink(struct dc_link *link,
dp_trace_init(link);
/* Connectivity log: detection */
+ dc_edid_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],
@@ -1424,7 +1425,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;
+ drm_edid_free(dc_sink->drm_edid);
dm_error("Bad EDID, status%d!\n", edid_status);
}
--
2.47.2
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v2 04/14] drm/edid: introduce a helper that gets monitor name from drm_edid
2025-05-07 0:03 ` [PATCH v2 04/14] drm/edid: introduce a helper that gets monitor name from drm_edid Melissa Wen
@ 2025-05-08 11:39 ` Jani Nikula
2025-05-13 21:42 ` Melissa Wen
0 siblings, 1 reply; 21+ messages in thread
From: Jani Nikula @ 2025-05-08 11:39 UTC (permalink / raw)
To: Melissa Wen, harry.wentland, sunpeng.li, alexander.deucher,
christian.koenig, airlied, simona, andrzej.hajda, neil.armstrong,
rfoss, maarten.lankhorst, mripard, tzimmermann
Cc: amd-gfx, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
Michel Daenzer, dri-devel, kernel-dev
On Tue, 06 May 2025, Melissa Wen <mwen@igalia.com> wrote:
> 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.
Should mention that this is just a temporary thing, and should be
removed later.
> 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 | 33 ++++++++++++++-----
> include/drm/drm_edid.h | 7 ++--
> 5 files changed, 32 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 b1085f1195f7..514da4d5d300 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
> @@ -134,7 +134,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
> edid_caps->manufacture_week = product_id.week_of_manufacture;
> edid_caps->manufacture_year = product_id.year_of_manufacture;
>
> - 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 28a2e1ee04b2..c2d60b9c28fd 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 3a1f1ffc7b55..b17a602516ee 100644
> --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> @@ -4896,7 +4896,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 13bc4c290b17..6e4cffd467f1 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -5575,27 +5575,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);
> }
>
> @@ -5603,6 +5599,25 @@ 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 should mention it's deprecated and all users should switch to
drm_edid_get_monitor_name(). Nobody should be using this.
> + */
> +void drm_edid_raw_get_monitor_name(const struct edid *edid, char *name, int bufsize)
> +{
> + struct drm_edid drm_edid = {
> + .edid = edid,
> + .size = edid ? edid_size(edid) : 0,
> + };
> +
See drm_edid_legacy_init() and its use in this file. Should switch to
that.
> + drm_edid_get_monitor_name(&drm_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 eaac5e665892..ceb522c4f4c2 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -441,8 +441,11 @@ 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_get_monitor_name(const struct drm_edid *drm_edid,
> + char *name,
> + int bufsize);
Please move this under the section:
/* Interface based on struct drm_edid */
further down.
> +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);
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 11/14] drm/amd/display: create a function to fill dc_sink with edid data
2025-05-07 0:04 ` [PATCH v2 11/14] drm/amd/display: create a function to fill dc_sink with edid data Melissa Wen
@ 2025-05-08 11:41 ` Jani Nikula
0 siblings, 0 replies; 21+ messages in thread
From: Jani Nikula @ 2025-05-08 11:41 UTC (permalink / raw)
To: Melissa Wen, harry.wentland, sunpeng.li, alexander.deucher,
christian.koenig, airlied, simona
Cc: amd-gfx, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
Michel Daenzer, dri-devel, kernel-dev
On Tue, 06 May 2025, Melissa Wen <mwen@igalia.com> wrote:
> From: Rodrigo Siqueira <siqueira@igalia.com>
>
> 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.
>
> Signed-off-by: Rodrigo Siqueira <siqueira@igalia.com>
> Co-developer--by: Melissa Wen <mwen@igalia.com>
> Signed-off-by: Melissa Wen <mwen@igalia.com>
> ---
> drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c | 8 ++++++++
> drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h | 2 ++
> drivers/gpu/drm/amd/display/dc/link/link_detection.c | 3 +--
> 3 files changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c
> index fab873b091f5..39fcaa16a14a 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.c
> @@ -17,3 +17,11 @@ bool dc_edid_is_same_edid(struct dc_sink *prev_sink,
> return (memcmp(old_edid->raw_edid,
> new_edid->raw_edid, new_edid->length) == 0);
> }
> +
> +void dc_edid_copy_edid_to_dc(struct dc_sink *dc_sink,
> + const void *edid,
> + int len)
> +{
> + memmove(dc_sink->dc_edid.raw_edid, (const uint8_t *) edid, len);
Superfluous cast.
> + dc_sink->dc_edid.length = len;
> +}
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h
> index 7e3b1177bc8a..f42cd5bbc730 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_edid.h
> @@ -7,5 +7,7 @@
>
> bool dc_edid_is_same_edid(struct dc_sink *prev_sink,
> struct dc_sink *current_sink);
> +void dc_edid_copy_edid_to_dc(struct dc_sink *dc_sink,
> + const void *edid, int len);
>
> #endif /* __DC_EDID_H__ */
> 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 e748721f31e4..978d2b4a4d29 100644
> --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
> @@ -1410,8 +1410,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;
> + dc_edid_copy_edid_to_dc(dc_sink, edid, len);
>
> if (!link_add_remote_sink_helper(
> link,
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 12/14] drm/edid: introduce a helper that compares edid data from two drm_edid
2025-05-07 0:04 ` [PATCH v2 12/14] drm/edid: introduce a helper that compares edid data from two drm_edid Melissa Wen
@ 2025-05-08 11:47 ` Jani Nikula
2025-05-13 21:45 ` Melissa Wen
0 siblings, 1 reply; 21+ messages in thread
From: Jani Nikula @ 2025-05-08 11:47 UTC (permalink / raw)
To: Melissa Wen, maarten.lankhorst, mripard, tzimmermann, airlied,
simona
Cc: amd-gfx, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
Michel Daenzer, dri-devel, kernel-dev
On Tue, 06 May 2025, Melissa Wen <mwen@igalia.com> wrote:
> 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
^
Theres's a non-breaking space in there I think.
> 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)
>
> 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 6e4cffd467f1..079042ccbc41 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1820,8 +1820,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;
> @@ -6918,7 +6918,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,
> @@ -7523,3 +7523,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_edid_eq - Check if EDIDs are equal
> + *
> + * @drm_edid_old: old drm_edid to compare edid
> + * @drm_edid_new: new drm_edid to compare edid
Comments still refer to old/new, please run kernel-doc.
> + *
> + * 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 ceb522c4f4c2..c0e49c4a32e9 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -472,6 +472,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_first,
> + const struct drm_edid *drm_edid_second);
Nitpick, parameter names in the declaration differ from the ones in the
definition.
With the above fixed,
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
> 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,
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 13/14] drm/amd/display: add drm_edid to dc_sink
2025-05-07 0:04 ` [PATCH v2 13/14] drm/amd/display: add drm_edid to dc_sink Melissa Wen
@ 2025-05-08 11:50 ` Jani Nikula
0 siblings, 0 replies; 21+ messages in thread
From: Jani Nikula @ 2025-05-08 11:50 UTC (permalink / raw)
To: Melissa Wen, harry.wentland, sunpeng.li, alexander.deucher,
christian.koenig, airlied, simona
Cc: amd-gfx, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
Michel Daenzer, dri-devel, kernel-dev
On Tue, 06 May 2025, Melissa Wen <mwen@igalia.com> wrote:
> diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
> index c93e074ea736..54f6ed33e373 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc.h
> @@ -46,6 +46,8 @@
>
> #include "dmub/inc/dmub_cmd.h"
>
> +#include <drm/drm_edid.h>
> +
Completely up to AMD maintainers, but in code I maintain I'd request
using a forward declaration instead of an include if you only need a
struct pointer. The header interdependencies just add up.
BR,
Jani.
> struct abm_save_restore;
>
> /* forward declaration */
> @@ -2433,6 +2435,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;
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 04/14] drm/edid: introduce a helper that gets monitor name from drm_edid
2025-05-08 11:39 ` Jani Nikula
@ 2025-05-13 21:42 ` Melissa Wen
0 siblings, 0 replies; 21+ messages in thread
From: Melissa Wen @ 2025-05-13 21:42 UTC (permalink / raw)
To: Jani Nikula, harry.wentland, sunpeng.li, alexander.deucher,
christian.koenig, airlied, simona, andrzej.hajda, neil.armstrong,
rfoss, maarten.lankhorst, mripard, tzimmermann
Cc: amd-gfx, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
Michel Daenzer, dri-devel, kernel-dev
On 08/05/2025 08:39, Jani Nikula wrote:
> On Tue, 06 May 2025, Melissa Wen <mwen@igalia.com> wrote:
>> 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.
> Should mention that this is just a temporary thing, and should be
> removed later.
ok
>
>> 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 | 33 ++++++++++++++-----
>> include/drm/drm_edid.h | 7 ++--
>> 5 files changed, 32 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 b1085f1195f7..514da4d5d300 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
>> @@ -134,7 +134,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
>> edid_caps->manufacture_week = product_id.week_of_manufacture;
>> edid_caps->manufacture_year = product_id.year_of_manufacture;
>>
>> - 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 28a2e1ee04b2..c2d60b9c28fd 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 3a1f1ffc7b55..b17a602516ee 100644
>> --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
>> +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
>> @@ -4896,7 +4896,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 13bc4c290b17..6e4cffd467f1 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -5575,27 +5575,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);
>> }
>>
>> @@ -5603,6 +5599,25 @@ 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 should mention it's deprecated and all users should switch to
> drm_edid_get_monitor_name(). Nobody should be using this.
ok
>> + */
>> +void drm_edid_raw_get_monitor_name(const struct edid *edid, char *name, int bufsize)
>> +{
>> + struct drm_edid drm_edid = {
>> + .edid = edid,
>> + .size = edid ? edid_size(edid) : 0,
>> + };
>> +
> See drm_edid_legacy_init() and its use in this file. Should switch to
> that.
ack. thanks for point it out.
>
>> + drm_edid_get_monitor_name(&drm_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 eaac5e665892..ceb522c4f4c2 100644
>> --- a/include/drm/drm_edid.h
>> +++ b/include/drm/drm_edid.h
>> @@ -441,8 +441,11 @@ 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_get_monitor_name(const struct drm_edid *drm_edid,
>> + char *name,
>> + int bufsize);
> Please move this under the section:
>
> /* Interface based on struct drm_edid */
>
> further down.
right.
Thanks for reviewing
>
>> +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);
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 12/14] drm/edid: introduce a helper that compares edid data from two drm_edid
2025-05-08 11:47 ` Jani Nikula
@ 2025-05-13 21:45 ` Melissa Wen
0 siblings, 0 replies; 21+ messages in thread
From: Melissa Wen @ 2025-05-13 21:45 UTC (permalink / raw)
To: Jani Nikula, maarten.lankhorst, mripard, tzimmermann, airlied,
simona
Cc: amd-gfx, Alex Hung, Mario Limonciello, Rodrigo Siqueira,
Michel Daenzer, dri-devel, kernel-dev
On 08/05/2025 08:47, Jani Nikula wrote:
> On Tue, 06 May 2025, Melissa Wen <mwen@igalia.com> wrote:
>> 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
> ^
>
> Theres's a non-breaking space in there I think.
>
>> 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)
>>
>> 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 6e4cffd467f1..079042ccbc41 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -1820,8 +1820,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;
>> @@ -6918,7 +6918,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,
>> @@ -7523,3 +7523,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_edid_eq - Check if EDIDs are equal
>> + *
>> + * @drm_edid_old: old drm_edid to compare edid
>> + * @drm_edid_new: new drm_edid to compare edid
> Comments still refer to old/new, please run kernel-doc.
>
>> + *
>> + * 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 ceb522c4f4c2..c0e49c4a32e9 100644
>> --- a/include/drm/drm_edid.h
>> +++ b/include/drm/drm_edid.h
>> @@ -472,6 +472,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_first,
>> + const struct drm_edid *drm_edid_second);
> Nitpick, parameter names in the declaration differ from the ones in the
> definition.
>
> With the above fixed,
>
> Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Oops. I'll address all comments in the next version.
Thanks,
Melissa
>
>
>> 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,
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2025-05-13 21:45 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-07 0:03 [PATCH v2 00/14] drm/amd/display: more drm_edid to AMD display driver Melissa Wen
2025-05-07 0:03 ` [PATCH v2 01/14] drm/amd/display: make sure drm_edid stored in aconnector doesn't leak Melissa Wen
2025-05-07 0:03 ` [PATCH v2 02/14] drm/amd/display: start using drm_edid helpers to parse EDID caps Melissa Wen
2025-05-07 0:03 ` [PATCH v2 03/14] drm/amd/display: use drm_edid_product_id for parsing EDID product info Melissa Wen
2025-05-07 0:03 ` [PATCH v2 04/14] drm/edid: introduce a helper that gets monitor name from drm_edid Melissa Wen
2025-05-08 11:39 ` Jani Nikula
2025-05-13 21:42 ` Melissa Wen
2025-05-07 0:03 ` [PATCH v2 05/14] drm/amd/display: get panel id with drm_edid helper Melissa Wen
2025-05-07 0:04 ` [PATCH v2 06/14] drm/amd/display: get SAD from drm_eld when parsing EDID caps Melissa Wen
2025-05-07 0:04 ` [PATCH v2 07/14] drm/amd/display: get SADB " Melissa Wen
2025-05-07 0:04 ` [PATCH v2 08/14] drm/amd/display: simplify dm_helpers_parse_edid_caps signature Melissa Wen
2025-05-07 0:04 ` [PATCH v2 09/14] drm/amd/display: change DC functions to accept private types for edid Melissa Wen
2025-05-07 0:04 ` [PATCH v2 10/14] drm/amd/display: add a mid-layer file to handle EDID in DC Melissa Wen
2025-05-07 0:04 ` [PATCH v2 11/14] drm/amd/display: create a function to fill dc_sink with edid data Melissa Wen
2025-05-08 11:41 ` Jani Nikula
2025-05-07 0:04 ` [PATCH v2 12/14] drm/edid: introduce a helper that compares edid data from two drm_edid Melissa Wen
2025-05-08 11:47 ` Jani Nikula
2025-05-13 21:45 ` Melissa Wen
2025-05-07 0:04 ` [PATCH v2 13/14] drm/amd/display: add drm_edid to dc_sink Melissa Wen
2025-05-08 11:50 ` Jani Nikula
2025-05-07 0:04 ` [PATCH v2 14/14] 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