Commit 391ef035 authored by Jerry (Fangzhi) Zuo's avatar Jerry (Fangzhi) Zuo Committed by Alex Deucher

drm/amd/display: Fix rehook MST display not light back on

Original applied dm_restore_drm_connector_state() has got removed.
Set link status to BAD before hotplug() event could trigger
another modeset from userspace.

The fix "Fix MST daisy chain SST not light up" commit makes so it is trying
to create a stream prior to dc_sink. That makes dc_sink is not present in
create_stream_for_sink().
Signed-off-by: default avatarJerry (Fangzhi) Zuo <Jerry.Zuo@amd.com>
Reviewed-by: default avatarRoman Li <Roman.Li@amd.com>
Acked-by: default avatarHarry Wentland <harry.wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 23bfb331
...@@ -2351,7 +2351,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, ...@@ -2351,7 +2351,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
const struct dm_connector_state *dm_state) const struct dm_connector_state *dm_state)
{ {
struct drm_display_mode *preferred_mode = NULL; struct drm_display_mode *preferred_mode = NULL;
const struct drm_connector *drm_connector; struct drm_connector *drm_connector;
struct dc_stream_state *stream = NULL; struct dc_stream_state *stream = NULL;
struct drm_display_mode mode = *drm_mode; struct drm_display_mode mode = *drm_mode;
bool native_mode_found = false; bool native_mode_found = false;
...@@ -2370,11 +2370,13 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, ...@@ -2370,11 +2370,13 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
if (!aconnector->dc_sink) { if (!aconnector->dc_sink) {
/* /*
* Exclude MST from creating fake_sink * Create dc_sink when necessary to MST
* TODO: need to enable MST into fake_sink feature * Don't apply fake_sink to MST
*/ */
if (aconnector->mst_port) if (aconnector->mst_port) {
goto stream_create_fail; dm_dp_mst_dc_sink_create(drm_connector);
goto mst_dc_sink_create_done;
}
if (create_fake_sink(aconnector)) if (create_fake_sink(aconnector))
goto stream_create_fail; goto stream_create_fail;
...@@ -2425,6 +2427,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, ...@@ -2425,6 +2427,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
stream_create_fail: stream_create_fail:
dm_state_null: dm_state_null:
drm_connector_null: drm_connector_null:
mst_dc_sink_create_done:
return stream; return stream;
} }
......
...@@ -189,6 +189,8 @@ struct amdgpu_dm_connector { ...@@ -189,6 +189,8 @@ struct amdgpu_dm_connector {
struct mutex hpd_lock; struct mutex hpd_lock;
bool fake_enable; bool fake_enable;
bool mst_connected;
}; };
#define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base) #define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base)
......
...@@ -180,6 +180,42 @@ static int dm_connector_update_modes(struct drm_connector *connector, ...@@ -180,6 +180,42 @@ static int dm_connector_update_modes(struct drm_connector *connector,
return drm_add_edid_modes(connector, edid); return drm_add_edid_modes(connector, edid);
} }
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);
...@@ -306,6 +342,7 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, ...@@ -306,6 +342,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;
} }
} }
...@@ -358,6 +395,8 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, ...@@ -358,6 +395,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);
...@@ -389,6 +428,8 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, ...@@ -389,6 +428,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)
...@@ -399,10 +440,18 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) ...@@ -399,10 +440,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);
...@@ -411,6 +460,8 @@ static void dm_dp_mst_register_connector(struct drm_connector *connector) ...@@ -411,6 +460,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 = {
......
...@@ -31,5 +31,6 @@ struct amdgpu_dm_connector; ...@@ -31,5 +31,6 @@ struct amdgpu_dm_connector;
void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
struct amdgpu_dm_connector *aconnector); struct amdgpu_dm_connector *aconnector);
void dm_dp_mst_dc_sink_create(struct drm_connector *connector);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment