a) Once EDID is parsed, the monitor HDMI support information is available
through drm_display_info.is_hdmi. The amdgpu driver still calls
drm_detect_hdmi_monitor() to retrieve the same information, which
is less efficient. Change to drm_display_info.is_hdmi

This is a TODO task in Documentation/gpu/todo.rst

b) drm_display_info is updated by drm_get_edid() or
drm_connector_update_edid_property(). In the amdgpu driver it is almost
always updated when the edid is read in amdgpu_connector_get_edid(),
but not always.  Change amdgpu_connector_get_edid() and
amdgpu_connector_free_edid() to keep drm_display_info updated. This allows a)
to work properly.

c) Use drm_edid_get_monitor_name() instead of duplicating the code that
parses the EDID in dm_helpers_parse_edid_caps()

Also, remove the unused "struct dc_context *ctx" parameter in
dm_helpers_parse_edid_caps()

Signed-off-by: Claudio Suarez <c...@net-c.es>
---
 .../gpu/drm/amd/amdgpu/amdgpu_connectors.c    | 23 +++++++----
 .../gpu/drm/amd/amdgpu/amdgpu_connectors.h    |  2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_encoders.c  |  4 +-
 .../gpu/drm/amd/amdgpu/atombios_encoders.c    |  6 +--
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  3 +-
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 39 ++++++-------------
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  2 +-
 drivers/gpu/drm/amd/display/dc/dm_helpers.h   |  2 +-
 9 files changed, 39 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
index b9c11c2b2885..7b41a1120b70 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
@@ -25,6 +25,7 @@
  */
 
 #include <drm/drm_edid.h>
+#include <drm/drm_connector.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_dp_helper.h>
 #include <drm/drm_probe_helper.h>
@@ -108,7 +109,7 @@ int amdgpu_connector_get_monitor_bpc(struct drm_connector 
*connector)
        case DRM_MODE_CONNECTOR_DVII:
        case DRM_MODE_CONNECTOR_HDMIB:
                if (amdgpu_connector->use_digital) {
-                       if 
(drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) {
+                       if (amdgpu_connector_is_hdmi_monitor(connector)) {
                                if (connector->display_info.bpc)
                                        bpc = connector->display_info.bpc;
                        }
@@ -116,7 +117,7 @@ int amdgpu_connector_get_monitor_bpc(struct drm_connector 
*connector)
                break;
        case DRM_MODE_CONNECTOR_DVID:
        case DRM_MODE_CONNECTOR_HDMIA:
-               if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) {
+               if (amdgpu_connector_is_hdmi_monitor(connector)) {
                        if (connector->display_info.bpc)
                                bpc = connector->display_info.bpc;
                }
@@ -125,7 +126,7 @@ int amdgpu_connector_get_monitor_bpc(struct drm_connector 
*connector)
                dig_connector = amdgpu_connector->con_priv;
                if ((dig_connector->dp_sink_type == 
CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
                    (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) ||
-                   drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) {
+                   (amdgpu_connector_is_hdmi_monitor(connector))) {
                        if (connector->display_info.bpc)
                                bpc = connector->display_info.bpc;
                }
@@ -149,7 +150,7 @@ int amdgpu_connector_get_monitor_bpc(struct drm_connector 
*connector)
                break;
        }
 
-       if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) {
+       if (amdgpu_connector_is_hdmi_monitor(connector)) {
                /*
                 * Pre DCE-8 hw can't handle > 12 bpc, and more than 12 bpc 
doesn't make
                 * much sense without support for > 12 bpc framebuffers. RGB 
4:4:4 at
@@ -315,8 +316,10 @@ static void amdgpu_connector_get_edid(struct drm_connector 
*connector)
        if (!amdgpu_connector->edid) {
                /* some laptops provide a hardcoded edid in rom for LCDs */
                if (((connector->connector_type == DRM_MODE_CONNECTOR_LVDS) ||
-                    (connector->connector_type == DRM_MODE_CONNECTOR_eDP)))
+                    (connector->connector_type == DRM_MODE_CONNECTOR_eDP))) {
                        amdgpu_connector->edid = 
amdgpu_connector_get_hardcoded_edid(adev);
+                       drm_connector_update_edid_property(connector, 
amdgpu_connector->edid);
+               }
        }
 }
 
@@ -326,6 +329,7 @@ static void amdgpu_connector_free_edid(struct drm_connector 
*connector)
 
        kfree(amdgpu_connector->edid);
        amdgpu_connector->edid = NULL;
+       drm_connector_update_edid_property(connector, NULL);
 }
 
 static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector)
@@ -1170,7 +1174,7 @@ static enum drm_mode_status 
amdgpu_connector_dvi_mode_valid(struct drm_connector
                    (amdgpu_connector->connector_object_id == 
CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) ||
                    (amdgpu_connector->connector_object_id == 
CONNECTOR_OBJECT_ID_HDMI_TYPE_B)) {
                        return MODE_OK;
-               } else if 
(drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) {
+               } else if (amdgpu_connector_is_hdmi_monitor(connector)) {
                        /* HDMI 1.3+ supports max clock of 340 Mhz */
                        if (mode->clock > 340000)
                                return MODE_CLOCK_HIGH;
@@ -1322,6 +1326,11 @@ bool amdgpu_connector_is_dp12_capable(struct 
drm_connector *connector)
        return false;
 }
 
+bool amdgpu_connector_is_hdmi_monitor(struct drm_connector *connector)
+{
+       return connector->display_info.is_hdmi;
+}
+
 static enum drm_connector_status
 amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)
 {
@@ -1462,7 +1471,7 @@ static enum drm_mode_status 
amdgpu_connector_dp_mode_valid(struct drm_connector
                    (amdgpu_dig_connector->dp_sink_type == 
CONNECTOR_OBJECT_ID_eDP)) {
                        return amdgpu_atombios_dp_mode_valid_helper(connector, 
mode);
                } else {
-                       if 
(drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) {
+                       if (amdgpu_connector_is_hdmi_monitor(connector)) {
                                /* HDMI 1.3+ supports max clock of 340 Mhz */
                                if (mode->clock > 340000)
                                        return MODE_CLOCK_HIGH;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.h
index 61fcef15ad72..0843540e01f2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.h
@@ -29,6 +29,8 @@ void amdgpu_connector_hotplug(struct drm_connector 
*connector);
 int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector);
 u16 amdgpu_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector 
*connector);
 bool amdgpu_connector_is_dp12_capable(struct drm_connector *connector);
+bool amdgpu_connector_is_hdmi_monitor(struct drm_connector *connector);
+
 void
 amdgpu_connector_add(struct amdgpu_device *adev,
                      uint32_t connector_id,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index dc50c05f23fc..41b43207e9fa 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1364,7 +1364,7 @@ bool amdgpu_display_crtc_scaling_mode_fixup(struct 
drm_crtc *crtc,
                if ((!(mode->flags & DRM_MODE_FLAG_INTERLACE)) &&
                    ((amdgpu_encoder->underscan_type == UNDERSCAN_ON) ||
                     ((amdgpu_encoder->underscan_type == UNDERSCAN_AUTO) &&
-                     drm_detect_hdmi_monitor(amdgpu_connector_edid(connector)) 
&&
+                     amdgpu_connector_is_hdmi_monitor(connector) &&
                      amdgpu_display_is_hdtv_mode(mode)))) {
                        if (amdgpu_encoder->underscan_hborder != 0)
                                amdgpu_crtc->h_border = 
amdgpu_encoder->underscan_hborder;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_encoders.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_encoders.c
index af4ef84e27a7..34799786bb40 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_encoders.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_encoders.c
@@ -222,7 +222,7 @@ bool amdgpu_dig_monitor_is_duallink(struct drm_encoder 
*encoder,
        case DRM_MODE_CONNECTOR_HDMIB:
                if (amdgpu_connector->use_digital) {
                        /* HDMI 1.3 supports up to 340 Mhz over single link */
-                       if 
(drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) {
+                       if (amdgpu_connector_is_hdmi_monitor(connector)) {
                                if (pixel_clock > 340000)
                                        return true;
                                else
@@ -244,7 +244,7 @@ bool amdgpu_dig_monitor_is_duallink(struct drm_encoder 
*encoder,
                        return false;
                else {
                        /* HDMI 1.3 supports up to 340 Mhz over single link */
-                       if 
(drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) {
+                       if (amdgpu_connector_is_hdmi_monitor(connector)) {
                                if (pixel_clock > 340000)
                                        return true;
                                else
diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c 
b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
index 6134ed964027..07c4ff14f2a7 100644
--- a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
+++ b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
@@ -469,7 +469,7 @@ int amdgpu_atombios_encoder_get_encoder_mode(struct 
drm_encoder *encoder)
                        if (amdgpu_connector->use_digital &&
                            (amdgpu_connector->audio == AMDGPU_AUDIO_ENABLE))
                                return ATOM_ENCODER_MODE_HDMI;
-                       else if 
(drm_detect_hdmi_monitor(amdgpu_connector_edid(connector)) &&
+                       else if (amdgpu_connector_is_hdmi_monitor(connector) &&
                                 (amdgpu_connector->audio == AMDGPU_AUDIO_AUTO))
                                return ATOM_ENCODER_MODE_HDMI;
                        else if (amdgpu_connector->use_digital)
@@ -488,7 +488,7 @@ int amdgpu_atombios_encoder_get_encoder_mode(struct 
drm_encoder *encoder)
                if (amdgpu_audio != 0) {
                        if (amdgpu_connector->audio == AMDGPU_AUDIO_ENABLE)
                                return ATOM_ENCODER_MODE_HDMI;
-                       else if 
(drm_detect_hdmi_monitor(amdgpu_connector_edid(connector)) &&
+                       else if (amdgpu_connector_is_hdmi_monitor(connector) &&
                                 (amdgpu_connector->audio == AMDGPU_AUDIO_AUTO))
                                return ATOM_ENCODER_MODE_HDMI;
                        else
@@ -506,7 +506,7 @@ int amdgpu_atombios_encoder_get_encoder_mode(struct 
drm_encoder *encoder)
                } else if (amdgpu_audio != 0) {
                        if (amdgpu_connector->audio == AMDGPU_AUDIO_ENABLE)
                                return ATOM_ENCODER_MODE_HDMI;
-                       else if 
(drm_detect_hdmi_monitor(amdgpu_connector_edid(connector)) &&
+                       else if (amdgpu_connector_is_hdmi_monitor(connector) &&
                                 (amdgpu_connector->audio == AMDGPU_AUDIO_AUTO))
                                return ATOM_ENCODER_MODE_HDMI;
                        else
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 1ea31dcc7a8b..02ecd216a556 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2583,13 +2583,12 @@ void amdgpu_dm_update_connector_after_detect(
                        aconnector->edid =
                                (struct edid *)sink->dc_edid.raw_edid;
 
-                       drm_connector_update_edid_property(connector,
-                                                          aconnector->edid);
                        if (aconnector->dc_link->aux_mode)
                                drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux,
                                                    aconnector->edid);
                }
 
+               drm_connector_update_edid_property(connector, aconnector->edid);
                amdgpu_dm_update_freesync_caps(connector, aconnector->edid);
                update_connector_ext_caps(aconnector);
        } else {
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 6fee12c91ef5..2051dd27ef3b 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
@@ -29,6 +29,7 @@
 
 #include <drm/drm_probe_helper.h>
 #include <drm/amdgpu_drm.h>
+#include <drm/drm_connector.h>
 #include <drm/drm_edid.h>
 
 #include "dm_services.h"
@@ -37,6 +38,7 @@
 #include "amdgpu_dm.h"
 #include "amdgpu_dm_irq.h"
 #include "amdgpu_dm_mst_types.h"
+#include "amdgpu_connectors.h"
 
 #include "dm_helpers.h"
 
@@ -50,16 +52,17 @@
  *     void
  * */
 enum dc_edid_status dm_helpers_parse_edid_caps(
-               struct dc_context *ctx,
+               struct dc_link *link,
                const struct dc_edid *edid,
                struct dc_edid_caps *edid_caps)
 {
+       struct amdgpu_dm_connector *aconnector = link->priv;
+       struct drm_connector *connector = &aconnector->base;
        struct edid *edid_buf = (struct edid *) edid->raw_edid;
        struct cea_sad *sads;
        int sad_count = -1;
        int sadb_count = -1;
        int i = 0;
-       int j = 0;
        uint8_t *sadb = NULL;
 
        enum dc_edid_status result = EDID_OK;
@@ -78,23 +81,11 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
        edid_caps->manufacture_week = edid_buf->mfg_week;
        edid_caps->manufacture_year = edid_buf->mfg_year;
 
-       /* One of the four detailed_timings stores the monitor name. It's
-        * stored in an array of length 13. */
-       for (i = 0; i < 4; i++) {
-               if (edid_buf->detailed_timings[i].data.other_data.type == 0xfc) 
{
-                       while (j < 13 && 
edid_buf->detailed_timings[i].data.other_data.data.str.str[j]) {
-                               if 
(edid_buf->detailed_timings[i].data.other_data.data.str.str[j] == '\n')
-                                       break;
-
-                               edid_caps->display_name[j] =
-                                       
edid_buf->detailed_timings[i].data.other_data.data.str.str[j];
-                               j++;
-                       }
-               }
-       }
+       drm_edid_get_monitor_name(edid_buf,
+                                 edid_caps->display_name,
+                                 AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS);
 
-       edid_caps->edid_hdmi = drm_detect_hdmi_monitor(
-                       (struct edid *) edid->raw_edid);
+       edid_caps->edid_hdmi = amdgpu_connector_is_hdmi_monitor(connector);
 
        sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads);
        if (sad_count <= 0)
@@ -610,14 +601,8 @@ enum dc_edid_status dm_helpers_read_local_edid(
                /* We don't need the original edid anymore */
                kfree(edid);
 
-               /* connector->display_info will be parsed from EDID and saved
-                * into drm_connector->display_info from edid by call stack
-                * below:
-                * drm_parse_ycbcr420_deep_color_info
-                * drm_parse_hdmi_forum_vsdb
-                * drm_parse_cea_ext
-                * drm_add_display_info
-                * drm_connector_update_edid_property
+               /* connector->display_info is parsed from EDID and saved
+                * into drm_connector->display_info
                 *
                 * drm_connector->display_info will be used by amdgpu_dm funcs,
                 * like fill_stream_properties_from_drm_display_mode
@@ -625,7 +610,7 @@ enum dc_edid_status dm_helpers_read_local_edid(
                amdgpu_dm_update_connector_after_detect(aconnector);
 
                edid_status = dm_helpers_parse_edid_caps(
-                                               ctx,
+                                               link,
                                                &sink->dc_edid,
                                                &sink->edid_caps);
 
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index c798c65d4276..5efe89fe6c2c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3254,7 +3254,7 @@ struct dc_sink *dc_link_add_remote_sink(
                goto fail_add_sink;
 
        edid_status = dm_helpers_parse_edid_caps(
-                       link->ctx,
+                       link,
                        &dc_sink->dc_edid,
                        &dc_sink->edid_caps);
 
diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h 
b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
index 9ab854293ace..94dc80060610 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
@@ -59,7 +59,7 @@ void dm_helpers_free_gpu_mem(
                void *pvMem);
 
 enum dc_edid_status dm_helpers_parse_edid_caps(
-       struct dc_context *ctx,
+       struct dc_link *link,
        const struct dc_edid *edid,
        struct dc_edid_caps *edid_caps);
 
-- 
2.33.0



Reply via email to