|
@@ -185,6 +185,42 @@ static int dm_connector_update_modes(struct drm_connector *connector,
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void dm_dp_mst_dc_sink_create(struct drm_connector *connector)
|
|
|
|
+{
|
|
|
|
+ struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
|
|
|
|
+ struct edid *edid;
|
|
|
|
+ struct dc_sink *dc_sink;
|
|
|
|
+ struct dc_sink_init_data init_params = {
|
|
|
|
+ .link = aconnector->dc_link,
|
|
|
|
+ .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
|
|
|
|
+
|
|
|
|
+ edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
|
|
|
|
+
|
|
|
|
+ if (!edid) {
|
|
|
|
+ drm_mode_connector_update_edid_property(
|
|
|
|
+ &aconnector->base,
|
|
|
|
+ NULL);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ aconnector->edid = edid;
|
|
|
|
+
|
|
|
|
+ dc_sink = dc_link_add_remote_sink(
|
|
|
|
+ aconnector->dc_link,
|
|
|
|
+ (uint8_t *)aconnector->edid,
|
|
|
|
+ (aconnector->edid->extensions + 1) * EDID_LENGTH,
|
|
|
|
+ &init_params);
|
|
|
|
+
|
|
|
|
+ dc_sink->priv = aconnector;
|
|
|
|
+ aconnector->dc_sink = dc_sink;
|
|
|
|
+
|
|
|
|
+ amdgpu_dm_add_sink_to_freesync_module(
|
|
|
|
+ connector, aconnector->edid);
|
|
|
|
+
|
|
|
|
+ drm_mode_connector_update_edid_property(
|
|
|
|
+ &aconnector->base, aconnector->edid);
|
|
|
|
+}
|
|
|
|
+
|
|
static int dm_dp_mst_get_modes(struct drm_connector *connector)
|
|
static int dm_dp_mst_get_modes(struct drm_connector *connector)
|
|
{
|
|
{
|
|
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
|
|
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
|
|
@@ -311,6 +347,7 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
|
|
drm_mode_connector_set_path_property(connector, pathprop);
|
|
drm_mode_connector_set_path_property(connector, pathprop);
|
|
|
|
|
|
drm_connector_list_iter_end(&conn_iter);
|
|
drm_connector_list_iter_end(&conn_iter);
|
|
|
|
+ aconnector->mst_connected = true;
|
|
return &aconnector->base;
|
|
return &aconnector->base;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -363,6 +400,8 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
|
|
*/
|
|
*/
|
|
amdgpu_dm_connector_funcs_reset(connector);
|
|
amdgpu_dm_connector_funcs_reset(connector);
|
|
|
|
|
|
|
|
+ aconnector->mst_connected = true;
|
|
|
|
+
|
|
DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n",
|
|
DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n",
|
|
aconnector, connector->base.id, aconnector->mst_port);
|
|
aconnector, connector->base.id, aconnector->mst_port);
|
|
|
|
|
|
@@ -394,6 +433,8 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
|
|
drm_mode_connector_update_edid_property(
|
|
drm_mode_connector_update_edid_property(
|
|
&aconnector->base,
|
|
&aconnector->base,
|
|
NULL);
|
|
NULL);
|
|
|
|
+
|
|
|
|
+ aconnector->mst_connected = false;
|
|
}
|
|
}
|
|
|
|
|
|
static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
|
|
static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
|
|
@@ -404,10 +445,18 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
|
|
drm_kms_helper_hotplug_event(dev);
|
|
drm_kms_helper_hotplug_event(dev);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void dm_dp_mst_link_status_reset(struct drm_connector *connector)
|
|
|
|
+{
|
|
|
|
+ mutex_lock(&connector->dev->mode_config.mutex);
|
|
|
|
+ drm_mode_connector_set_link_status_property(connector, DRM_MODE_LINK_STATUS_BAD);
|
|
|
|
+ mutex_unlock(&connector->dev->mode_config.mutex);
|
|
|
|
+}
|
|
|
|
+
|
|
static void dm_dp_mst_register_connector(struct drm_connector *connector)
|
|
static void dm_dp_mst_register_connector(struct drm_connector *connector)
|
|
{
|
|
{
|
|
struct drm_device *dev = connector->dev;
|
|
struct drm_device *dev = connector->dev;
|
|
struct amdgpu_device *adev = dev->dev_private;
|
|
struct amdgpu_device *adev = dev->dev_private;
|
|
|
|
+ struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
|
|
|
|
|
|
if (adev->mode_info.rfbdev)
|
|
if (adev->mode_info.rfbdev)
|
|
drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector);
|
|
drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector);
|
|
@@ -416,6 +465,8 @@ static void dm_dp_mst_register_connector(struct drm_connector *connector)
|
|
|
|
|
|
drm_connector_register(connector);
|
|
drm_connector_register(connector);
|
|
|
|
|
|
|
|
+ if (aconnector->mst_connected)
|
|
|
|
+ dm_dp_mst_link_status_reset(connector);
|
|
}
|
|
}
|
|
|
|
|
|
static const struct drm_dp_mst_topology_cbs dm_mst_cbs = {
|
|
static const struct drm_dp_mst_topology_cbs dm_mst_cbs = {
|