Merge tag 'amd-drm-next-5.10-2020-09-03' of git://people.freedesktop.org/~agd5f/linux...
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / amdgpu_dm / amdgpu_dm.c
index b91ae0f..ec29376 100644 (file)
@@ -127,6 +127,42 @@ MODULE_FIRMWARE(FIRMWARE_NAVI12_DMCU);
 static int amdgpu_dm_init(struct amdgpu_device *adev);
 static void amdgpu_dm_fini(struct amdgpu_device *adev);
 
+static enum drm_mode_subconnector get_subconnector_type(struct dc_link *link)
+{
+       switch (link->dpcd_caps.dongle_type) {
+       case DISPLAY_DONGLE_NONE:
+               return DRM_MODE_SUBCONNECTOR_Native;
+       case DISPLAY_DONGLE_DP_VGA_CONVERTER:
+               return DRM_MODE_SUBCONNECTOR_VGA;
+       case DISPLAY_DONGLE_DP_DVI_CONVERTER:
+       case DISPLAY_DONGLE_DP_DVI_DONGLE:
+               return DRM_MODE_SUBCONNECTOR_DVID;
+       case DISPLAY_DONGLE_DP_HDMI_CONVERTER:
+       case DISPLAY_DONGLE_DP_HDMI_DONGLE:
+               return DRM_MODE_SUBCONNECTOR_HDMIA;
+       case DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE:
+       default:
+               return DRM_MODE_SUBCONNECTOR_Unknown;
+       }
+}
+
+static void update_subconnector_property(struct amdgpu_dm_connector *aconnector)
+{
+       struct dc_link *link = aconnector->dc_link;
+       struct drm_connector *connector = &aconnector->base;
+       enum drm_mode_subconnector subconnector = DRM_MODE_SUBCONNECTOR_Unknown;
+
+       if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
+               return;
+
+       if (aconnector->dc_sink)
+               subconnector = get_subconnector_type(link);
+
+       drm_object_property_set_value(&connector->base,
+                       connector->dev->mode_config.dp_subconnector_property,
+                       subconnector);
+}
+
 /*
  * initializes drm_device display related structures, based on the information
  * provided by DAL. The drm strcutures are: drm_crtc, drm_connector,
@@ -1389,7 +1425,7 @@ static int dm_late_init(void *handle)
        struct dmcu *dmcu = NULL;
        bool ret = true;
 
-       if (!adev->dm.fw_dmcu)
+       if (!adev->dm.fw_dmcu && !adev->dm.dmub_fw)
                return detect_mst_link_for_all_connectors(adev_to_drm(adev));
 
        dmcu = adev->dm.dc->res_pool->dmcu;
@@ -2101,7 +2137,6 @@ void amdgpu_dm_update_connector_after_detect(
        if (aconnector->mst_mgr.mst_state == true)
                return;
 
-
        sink = aconnector->dc_link->local_sink;
        if (sink)
                dc_sink_retain(sink);
@@ -2228,6 +2263,8 @@ void amdgpu_dm_update_connector_after_detect(
 
        mutex_unlock(&dev->mode_config.mutex);
 
+       update_subconnector_property(aconnector);
+
        if (sink)
                dc_sink_release(sink);
 }
@@ -4747,9 +4784,7 @@ static void dm_crtc_reset_state(struct drm_crtc *crtc)
        if (WARN_ON(!state))
                return;
 
-       crtc->state = &state->base;
-       crtc->state->crtc = crtc;
-
+       __drm_atomic_helper_crtc_reset(crtc, &state->base);
 }
 
 static struct drm_crtc_state *
@@ -4875,6 +4910,8 @@ amdgpu_dm_connector_detect(struct drm_connector *connector, bool force)
        else
                connected = (aconnector->base.force == DRM_FORCE_ON);
 
+       update_subconnector_property(aconnector);
+
        return (connected ? connector_status_connected :
                        connector_status_disconnected);
 }