Reduce direct handling of edid data by resorting to drm helpers that
deal with this info inside drm_edid infrastructure.
v3:
- use dc_edid_sink_edid_free in link_detection
Signed-off-by: Melissa Wen <m...@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 c7efeb9f38b6..ec33a6236e37 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"
@@ -3708,6 +3709,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.
@@ -3719,16 +3722,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);
@@ -7378,12 +7380,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);
}
}
@@ -7416,7 +7414,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)
@@ -7436,12 +7433,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 abfce44dcee7..3e9d04760c21 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,
@@ -100,20 +101,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;
@@ -135,10 +132,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) {
@@ -158,8 +153,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;
}
@@ -991,7 +984,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;
@@ -1021,11 +1013,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);