Commit 83a79dd6 authored by Wayne Lin's avatar Wayne Lin Committed by Alex Deucher

drm/amd/display: adjust flow for deallocation mst payload

[Why]
MST relevant variables are maintained at drm side. As the result, we
still have to call drm_dp_remove_payload_part2() to update the relevant
values regardless the link is under mst mode or not. We used to have a
workaround patch to tackle this: commit 3d8fcc67 ("drm/amd/display:
Extract temp drm mst deallocation wa into its own function")

Now it's time to remove the workaround and adjust the flow.

[How]
During deallocate_mst_payload(), source actually doesn't send out
ALLOCATE_PAYLOAD at the end as like the flow in allocate_mst_payload().
Call function dm_helpers_dp_mst_send_payload_allocation() at the end of
deallocate_mst_payload() is a bit confusing.

Separate dm_helpers_dp_mst_send_payload_allocation() into 2 functions.
Have a new function dm_helpers_dp_mst_update_mst_mgr_for_deallocation()
to replace dm_helpers_dp_mst_send_payload_allocation() for payload
deallocation.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Acked-by: default avatarHamza Mahfooz <hamza.mahfooz@amd.com>
Signed-off-by: default avatarWayne Lin <wayne.lin@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 43b8ac4b
......@@ -1715,23 +1715,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
/* TODO: Remove after DP2 receiver gets proper support of Cable ID feature */
adev->dm.dc->debug.ignore_cable_id = true;
/* TODO: There is a new drm mst change where the freedom of
* vc_next_start_slot update is revoked/moved into drm, instead of in
* driver. This forces us to make sure to get vc_next_start_slot updated
* in drm function each time without considering if mst_state is active
* or not. Otherwise, next time hotplug will give wrong start_slot
* number. We are implementing a temporary solution to even notify drm
* mst deallocation when link is no longer of MST type when uncommitting
* the stream so we will have more time to work on a proper solution.
* Ideally when dm_helpers_dp_mst_stop_top_mgr message is triggered, we
* should notify drm to do a complete "reset" of its states and stop
* calling further drm mst functions when link is no longer of an MST
* type. This could happen when we unplug an MST hubs/displays. When
* uncommit stream comes later after unplug, we should just reset
* hardware states only.
*/
adev->dm.dc->debug.temp_mst_deallocation_sequence = true;
if (adev->dm.dc->caps.dp_hdmi21_pcon_support)
DRM_INFO("DP-HDMI FRL PCON supported\n");
......
......@@ -333,15 +333,14 @@ enum act_return_status dm_helpers_dp_mst_poll_for_allocation_change_trigger(
return ACT_SUCCESS;
}
bool dm_helpers_dp_mst_send_payload_allocation(
void dm_helpers_dp_mst_send_payload_allocation(
struct dc_context *ctx,
const struct dc_stream_state *stream,
bool enable)
const struct dc_stream_state *stream)
{
struct amdgpu_dm_connector *aconnector;
struct drm_dp_mst_topology_state *mst_state;
struct drm_dp_mst_topology_mgr *mst_mgr;
struct drm_dp_mst_atomic_payload *new_payload, old_payload;
struct drm_dp_mst_atomic_payload *new_payload;
enum mst_progress_status set_flag = MST_ALLOCATE_NEW_PAYLOAD;
enum mst_progress_status clr_flag = MST_CLEAR_ALLOCATED_PAYLOAD;
int ret = 0;
......@@ -349,25 +348,13 @@ bool dm_helpers_dp_mst_send_payload_allocation(
aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
if (!aconnector || !aconnector->mst_root)
return false;
return;
mst_mgr = &aconnector->mst_root->mst_mgr;
mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);
new_payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
if (!enable) {
set_flag = MST_CLEAR_ALLOCATED_PAYLOAD;
clr_flag = MST_ALLOCATE_NEW_PAYLOAD;
}
if (enable) {
ret = drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, new_payload);
} else {
dm_helpers_construct_old_payload(mst_mgr, mst_state,
new_payload, &old_payload);
drm_dp_remove_payload_part2(mst_mgr, mst_state, &old_payload, new_payload);
}
ret = drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, new_payload);
if (ret) {
amdgpu_dm_set_mst_status(&aconnector->mst_status,
......@@ -378,10 +365,36 @@ bool dm_helpers_dp_mst_send_payload_allocation(
amdgpu_dm_set_mst_status(&aconnector->mst_status,
clr_flag, false);
}
return true;
}
void dm_helpers_dp_mst_update_mst_mgr_for_deallocation(
struct dc_context *ctx,
const struct dc_stream_state *stream)
{
struct amdgpu_dm_connector *aconnector;
struct drm_dp_mst_topology_state *mst_state;
struct drm_dp_mst_topology_mgr *mst_mgr;
struct drm_dp_mst_atomic_payload *new_payload, old_payload;
enum mst_progress_status set_flag = MST_CLEAR_ALLOCATED_PAYLOAD;
enum mst_progress_status clr_flag = MST_ALLOCATE_NEW_PAYLOAD;
aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
if (!aconnector || !aconnector->mst_root)
return;
mst_mgr = &aconnector->mst_root->mst_mgr;
mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);
new_payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
dm_helpers_construct_old_payload(mst_mgr, mst_state,
new_payload, &old_payload);
drm_dp_remove_payload_part2(mst_mgr, mst_state, &old_payload, new_payload);
amdgpu_dm_set_mst_status(&aconnector->mst_status, set_flag, true);
amdgpu_dm_set_mst_status(&aconnector->mst_status, clr_flag, false);
}
void dm_dtn_log_begin(struct dc_context *ctx,
struct dc_log_buffer_ctx *log_ctx)
{
......
......@@ -956,7 +956,6 @@ struct dc_debug_options {
unsigned int min_prefetch_in_strobe_ns;
bool disable_unbounded_requesting;
bool dig_fifo_off_in_blank;
bool temp_mst_deallocation_sequence;
bool override_dispclk_programming;
bool otg_crc_db;
bool disallow_dispclk_dppclk_ds;
......
......@@ -103,10 +103,16 @@ enum act_return_status dm_helpers_dp_mst_poll_for_allocation_change_trigger(
/*
* Sends ALLOCATE_PAYLOAD message.
*/
bool dm_helpers_dp_mst_send_payload_allocation(
void dm_helpers_dp_mst_send_payload_allocation(
struct dc_context *ctx,
const struct dc_stream_state *stream,
bool enable);
const struct dc_stream_state *stream);
/*
* Update mst manager relevant variables
*/
void dm_helpers_dp_mst_update_mst_mgr_for_deallocation(
struct dc_context *ctx,
const struct dc_stream_state *stream);
bool dm_helpers_dp_mst_start_top_mgr(
struct dc_context *ctx,
......
......@@ -1247,86 +1247,6 @@ static void remove_stream_from_alloc_table(
}
}
static enum dc_status deallocate_mst_payload_with_temp_drm_wa(
struct pipe_ctx *pipe_ctx)
{
struct dc_stream_state *stream = pipe_ctx->stream;
struct dc_link *link = stream->link;
struct dc_dp_mst_stream_allocation_table proposed_table = {0};
struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0);
int i;
bool mst_mode = (link->type == dc_connection_mst_branch);
/* adjust for drm changes*/
const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
const struct dc_link_settings empty_link_settings = {0};
DC_LOGGER_INIT(link->ctx->logger);
if (link_hwss->ext.set_throttled_vcp_size)
link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
if (link_hwss->ext.set_hblank_min_symbol_width)
link_hwss->ext.set_hblank_min_symbol_width(pipe_ctx,
&empty_link_settings,
avg_time_slots_per_mtp);
if (dm_helpers_dp_mst_write_payload_allocation_table(
stream->ctx,
stream,
&proposed_table,
false))
update_mst_stream_alloc_table(
link,
pipe_ctx->stream_res.stream_enc,
pipe_ctx->stream_res.hpo_dp_stream_enc,
&proposed_table);
else
DC_LOG_WARNING("Failed to update"
"MST allocation table for"
"pipe idx:%d\n",
pipe_ctx->pipe_idx);
DC_LOG_MST("%s"
"stream_count: %d: ",
__func__,
link->mst_stream_alloc_table.stream_count);
for (i = 0; i < MAX_CONTROLLER_NUM; i++) {
DC_LOG_MST("stream_enc[%d]: %p "
"stream[%d].hpo_dp_stream_enc: %p "
"stream[%d].vcp_id: %d "
"stream[%d].slot_count: %d\n",
i,
(void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc,
i,
(void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc,
i,
link->mst_stream_alloc_table.stream_allocations[i].vcp_id,
i,
link->mst_stream_alloc_table.stream_allocations[i].slot_count);
}
if (link_hwss->ext.update_stream_allocation_table == NULL ||
link_dp_get_encoding_format(&link->cur_link_settings) == DP_UNKNOWN_ENCODING) {
DC_LOG_DEBUG("Unknown encoding format\n");
return DC_ERROR_UNEXPECTED;
}
link_hwss->ext.update_stream_allocation_table(link, &pipe_ctx->link_res,
&link->mst_stream_alloc_table);
if (mst_mode) {
dm_helpers_dp_mst_poll_for_allocation_change_trigger(
stream->ctx,
stream);
}
dm_helpers_dp_mst_send_payload_allocation(
stream->ctx,
stream,
false);
return DC_OK;
}
static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
{
struct dc_stream_state *stream = pipe_ctx->stream;
......@@ -1339,9 +1259,6 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
const struct dc_link_settings empty_link_settings = {0};
DC_LOGGER_INIT(link->ctx->logger);
if (link->dc->debug.temp_mst_deallocation_sequence)
return deallocate_mst_payload_with_temp_drm_wa(pipe_ctx);
/* deallocate_mst_payload is called before disable link. When mode or
* disable/enable monitor, new stream is created which is not in link
* stream[] yet. For this, payload is not allocated yet, so de-alloc
......@@ -1414,16 +1331,14 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
link_hwss->ext.update_stream_allocation_table(link, &pipe_ctx->link_res,
&link->mst_stream_alloc_table);
if (mst_mode) {
if (mst_mode)
dm_helpers_dp_mst_poll_for_allocation_change_trigger(
stream->ctx,
stream);
dm_helpers_dp_mst_send_payload_allocation(
stream->ctx,
stream,
false);
}
dm_helpers_dp_mst_update_mst_mgr_for_deallocation(
stream->ctx,
stream);
return DC_OK;
}
......@@ -1504,12 +1419,10 @@ static enum dc_status allocate_mst_payload(struct pipe_ctx *pipe_ctx)
stream->ctx,
stream);
if (ret != ACT_LINK_LOST) {
if (ret != ACT_LINK_LOST)
dm_helpers_dp_mst_send_payload_allocation(
stream->ctx,
stream,
true);
}
stream);
/* slot X.Y for only current stream */
pbn_per_slot = get_pbn_per_slot(stream);
......@@ -1769,8 +1682,7 @@ enum dc_status link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in
/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
dm_helpers_dp_mst_send_payload_allocation(
stream->ctx,
stream,
true);
stream);
/* notify immediate branch device table update */
if (dm_helpers_dp_mst_write_payload_allocation_table(
......@@ -1899,8 +1811,7 @@ enum dc_status link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_
/* send ALLOCATE_PAYLOAD sideband message with updated pbn */
dm_helpers_dp_mst_send_payload_allocation(
stream->ctx,
stream,
true);
stream);
}
/* increase throttled vcp size */
......
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