Skip to content

Commit

Permalink
drm/amd/display: Fix rehook MST display not light back on
Browse files Browse the repository at this point in the history
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: Jerry (Fangzhi) Zuo <Jerry.Zuo@amd.com>
Reviewed-by: Roman Li <Roman.Li@amd.com>
Acked-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
  • Loading branch information
Jerry (Fangzhi) Zuo authored and Alex Deucher committed Dec 15, 2017
1 parent 7828850 commit becd087
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 5 deletions.
13 changes: 8 additions & 5 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2336,7 +2336,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
const struct dm_connector_state *dm_state)
{
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 drm_display_mode mode = *drm_mode;
bool native_mode_found = false;
Expand All @@ -2355,11 +2355,13 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,

if (!aconnector->dc_sink) {
/*
* Exclude MST from creating fake_sink
* TODO: need to enable MST into fake_sink feature
* Create dc_sink when necessary to MST
* Don't apply fake_sink to MST
*/
if (aconnector->mst_port)
goto stream_create_fail;
if (aconnector->mst_port) {
dm_dp_mst_dc_sink_create(drm_connector);
goto mst_dc_sink_create_done;
}

if (create_fake_sink(aconnector))
goto stream_create_fail;
Expand Down Expand Up @@ -2410,6 +2412,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
stream_create_fail:
dm_state_null:
drm_connector_null:
mst_dc_sink_create_done:
return stream;
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ struct amdgpu_dm_connector {
struct mutex hpd_lock;

bool fake_enable;

bool mst_connected;
};

#define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base)
Expand Down
51 changes: 51 additions & 0 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,42 @@ static int dm_connector_update_modes(struct drm_connector *connector,
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)
{
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
Expand Down Expand Up @@ -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_connector_list_iter_end(&conn_iter);
aconnector->mst_connected = true;
return &aconnector->base;
}
}
Expand Down Expand Up @@ -363,6 +400,8 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
*/
amdgpu_dm_connector_funcs_reset(connector);

aconnector->mst_connected = true;

DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n",
aconnector, connector->base.id, aconnector->mst_port);

Expand Down Expand Up @@ -394,6 +433,8 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
drm_mode_connector_update_edid_property(
&aconnector->base,
NULL);

aconnector->mst_connected = false;
}

static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
Expand All @@ -404,10 +445,18 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
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)
{
struct drm_device *dev = connector->dev;
struct amdgpu_device *adev = dev->dev_private;
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);

if (adev->mode_info.rfbdev)
drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector);
Expand All @@ -416,6 +465,8 @@ static void dm_dp_mst_register_connector(struct drm_connector *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 = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ struct amdgpu_dm_connector;

void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
struct amdgpu_dm_connector *aconnector);
void dm_dp_mst_dc_sink_create(struct drm_connector *connector);

#endif

0 comments on commit becd087

Please sign in to comment.