]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blobdiff - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
Merge tag 'amd-drm-next-5.10-2020-09-03' of git://people.freedesktop.org/~agd5f/linux...
[mirror_ubuntu-jammy-kernel.git] / drivers / gpu / drm / amd / display / amdgpu_dm / amdgpu_dm.c
index ec6710f6c8736d619e4a974a71823f33a97df669..ec29376667df2a578eb88a83c6718014c419f63d 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);
 }
@@ -2905,12 +2942,18 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev)
                                    &dm_atomic_state_funcs);
 
        r = amdgpu_display_modeset_create_props(adev);
-       if (r)
+       if (r) {
+               dc_release_state(state->context);
+               kfree(state);
                return r;
+       }
 
        r = amdgpu_dm_audio_init(adev);
-       if (r)
+       if (r) {
+               dc_release_state(state->context);
+               kfree(state);
                return r;
+       }
 
        return 0;
 }
@@ -4685,7 +4728,8 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
        update_stream_signal(stream, sink);
 
        if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
-               mod_build_hf_vsif_infopacket(stream, &stream->vsp_infopacket, false, false);
+               mod_build_hf_vsif_infopacket(stream, &stream->vsp_infopacket);
+
        if (stream->link->psr_settings.psr_feature_enabled) {
                //
                // should decide stream support vsc sdp colorimetry capability
@@ -4740,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 *
@@ -4868,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);
 }
@@ -4986,6 +5030,7 @@ static void amdgpu_dm_connector_destroy(struct drm_connector *connector)
        struct amdgpu_device *adev = drm_to_adev(connector->dev);
        struct amdgpu_display_manager *dm = &adev->dm;
 
+       drm_atomic_private_obj_fini(&aconnector->mst_mgr.base);
 #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||\
        defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)