Commit 3c4d55c9 authored by Aurabindo Pillai's avatar Aurabindo Pillai Committed by Alex Deucher

drm/amd/display: turn DPMS off on connector unplug

[Why&How]

Set dpms off on the connector that was unplugged, for the side effect of
releasing some references held through deallocation of MST payload. This is
the expected behaviour for non MST devices as well.
Signed-off-by: default avatarAurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: default avatarEryk Brol <eryk.brol@amd.com>
Reviewed-by: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 3f16ae82
...@@ -1984,6 +1984,33 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state, ...@@ -1984,6 +1984,33 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state,
return; return;
} }
static void dm_set_dpms_off(struct dc_link *link)
{
struct dc_stream_state *stream_state;
struct amdgpu_dm_connector *aconnector = link->priv;
struct amdgpu_device *adev = drm_to_adev(aconnector->base.dev);
struct dc_stream_update stream_update;
bool dpms_off = true;
memset(&stream_update, 0, sizeof(stream_update));
stream_update.dpms_off = &dpms_off;
mutex_lock(&adev->dm.dc_lock);
stream_state = dc_stream_find_from_link(link);
if (stream_state == NULL) {
DRM_DEBUG_DRIVER("Error finding stream state associated with link!\n");
mutex_unlock(&adev->dm.dc_lock);
return;
}
stream_update.stream = stream_state;
dc_commit_updates_for_stream(stream_state->ctx->dc, NULL, 0,
stream_state, &stream_update,
stream_state->ctx->dc->current_state);
mutex_unlock(&adev->dm.dc_lock);
}
static int dm_resume(void *handle) static int dm_resume(void *handle)
{ {
struct amdgpu_device *adev = handle; struct amdgpu_device *adev = handle;
...@@ -2434,8 +2461,11 @@ static void handle_hpd_irq(void *param) ...@@ -2434,8 +2461,11 @@ static void handle_hpd_irq(void *param)
drm_kms_helper_hotplug_event(dev); drm_kms_helper_hotplug_event(dev);
} else if (dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD)) { } else if (dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD)) {
amdgpu_dm_update_connector_after_detect(aconnector); if (new_connection_type == dc_connection_none &&
aconnector->dc_link->type == dc_connection_none)
dm_set_dpms_off(aconnector->dc_link);
amdgpu_dm_update_connector_after_detect(aconnector);
drm_modeset_lock_all(dev); drm_modeset_lock_all(dev);
dm_restore_drm_connector_state(dev, connector); dm_restore_drm_connector_state(dev, connector);
......
...@@ -2798,6 +2798,19 @@ struct dc_stream_state *dc_get_stream_at_index(struct dc *dc, uint8_t i) ...@@ -2798,6 +2798,19 @@ struct dc_stream_state *dc_get_stream_at_index(struct dc *dc, uint8_t i)
return NULL; return NULL;
} }
struct dc_stream_state *dc_stream_find_from_link(const struct dc_link *link)
{
uint8_t i;
struct dc_context *ctx = link->ctx;
for (i = 0; i < ctx->dc->current_state->stream_count; i++) {
if (ctx->dc->current_state->streams[i]->link == link)
return ctx->dc->current_state->streams[i];
}
return NULL;
}
enum dc_irq_source dc_interrupt_to_irq_source( enum dc_irq_source dc_interrupt_to_irq_source(
struct dc *dc, struct dc *dc,
uint32_t src_id, uint32_t src_id,
......
...@@ -292,6 +292,7 @@ void dc_stream_log(const struct dc *dc, const struct dc_stream_state *stream); ...@@ -292,6 +292,7 @@ void dc_stream_log(const struct dc *dc, const struct dc_stream_state *stream);
uint8_t dc_get_current_stream_count(struct dc *dc); uint8_t dc_get_current_stream_count(struct dc *dc);
struct dc_stream_state *dc_get_stream_at_index(struct dc *dc, uint8_t i); struct dc_stream_state *dc_get_stream_at_index(struct dc *dc, uint8_t i);
struct dc_stream_state *dc_stream_find_from_link(const struct dc_link *link);
/* /*
* Return the current frame counter. * Return the current frame counter.
......
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