drm/amd/display: Add option to defer works of hpd_rx_irq
[Why & How] Due to some code flow constraints, we need to defer dc_lock needed works from dc_link_handle_hpd_rx_irq(). Thus, do following changes: * Change allow_hpd_rx_irq() from static to public * Change handle_automated_test() from static to public * Extract link lost handling flow out from dc_link_handle_hpd_rx_irq() and put those into a new function dc_link_dp_handle_link_loss() * Add one option parameter to decide whether defer works within dc_link_handle_hpd_rx_irq() Acked-by: Mikita Lipski <mikita.lipski@amd.com> Signed-off-by: Wayne Lin <Wayne.Lin@amd.com> Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
928adbf65b
commit
410ad92d7f
@ -3431,7 +3431,7 @@ void decide_link_settings(struct dc_stream_state *stream,
|
||||
}
|
||||
|
||||
/*************************Short Pulse IRQ***************************/
|
||||
static bool allow_hpd_rx_irq(const struct dc_link *link)
|
||||
bool dc_link_dp_allow_hpd_rx_irq(const struct dc_link *link)
|
||||
{
|
||||
/*
|
||||
* Don't handle RX IRQ unless one of following is met:
|
||||
@ -3940,7 +3940,7 @@ static void dp_test_get_audio_test_data(struct dc_link *link, bool disable_video
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_automated_test(struct dc_link *link)
|
||||
void dc_link_dp_handle_automated_test(struct dc_link *link)
|
||||
{
|
||||
union test_request test_request;
|
||||
union test_response test_response;
|
||||
@ -3989,17 +3989,50 @@ static void handle_automated_test(struct dc_link *link)
|
||||
sizeof(test_response));
|
||||
}
|
||||
|
||||
bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss)
|
||||
void dc_link_dp_handle_link_loss(struct dc_link *link)
|
||||
{
|
||||
int i;
|
||||
struct pipe_ctx *pipe_ctx;
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link)
|
||||
break;
|
||||
}
|
||||
|
||||
if (pipe_ctx == NULL || pipe_ctx->stream == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
|
||||
pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) {
|
||||
core_link_disable_stream(pipe_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
|
||||
pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) {
|
||||
core_link_enable_stream(link->dc->current_state, pipe_ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss,
|
||||
bool defer_handling, bool *has_left_work)
|
||||
{
|
||||
union hpd_irq_data hpd_irq_dpcd_data = { { { {0} } } };
|
||||
union device_service_irq device_service_clear = { { 0 } };
|
||||
enum dc_status result;
|
||||
bool status = false;
|
||||
struct pipe_ctx *pipe_ctx;
|
||||
int i;
|
||||
|
||||
if (out_link_loss)
|
||||
*out_link_loss = false;
|
||||
|
||||
if (has_left_work)
|
||||
*has_left_work = false;
|
||||
/* For use cases related to down stream connection status change,
|
||||
* PSR and device auto test, refer to function handle_sst_hpd_irq
|
||||
* in DAL2.1*/
|
||||
@ -4031,11 +4064,14 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd
|
||||
&device_service_clear.raw,
|
||||
sizeof(device_service_clear.raw));
|
||||
device_service_clear.raw = 0;
|
||||
handle_automated_test(link);
|
||||
if (defer_handling && has_left_work)
|
||||
*has_left_work = true;
|
||||
else
|
||||
dc_link_dp_handle_automated_test(link);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!allow_hpd_rx_irq(link)) {
|
||||
if (!dc_link_dp_allow_hpd_rx_irq(link)) {
|
||||
DC_LOG_HW_HPD_IRQ("%s: skipping HPD handling on %d\n",
|
||||
__func__, link->link_index);
|
||||
return false;
|
||||
@ -4049,12 +4085,18 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd
|
||||
* so do not handle as a normal sink status change interrupt.
|
||||
*/
|
||||
|
||||
if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.UP_REQ_MSG_RDY)
|
||||
if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.UP_REQ_MSG_RDY) {
|
||||
if (defer_handling && has_left_work)
|
||||
*has_left_work = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* check if we have MST msg and return since we poll for it */
|
||||
if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.DOWN_REP_MSG_RDY)
|
||||
if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.DOWN_REP_MSG_RDY) {
|
||||
if (defer_handling && has_left_work)
|
||||
*has_left_work = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* For now we only handle 'Downstream port status' case.
|
||||
* If we got sink count changed it means
|
||||
@ -4071,29 +4113,10 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd
|
||||
sizeof(hpd_irq_dpcd_data),
|
||||
"Status: ");
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link)
|
||||
break;
|
||||
}
|
||||
|
||||
if (pipe_ctx == NULL || pipe_ctx->stream == NULL)
|
||||
return false;
|
||||
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
|
||||
pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe)
|
||||
core_link_disable_stream(pipe_ctx);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
|
||||
pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe)
|
||||
core_link_enable_stream(link->dc->current_state, pipe_ctx);
|
||||
}
|
||||
if (defer_handling && has_left_work)
|
||||
*has_left_work = true;
|
||||
else
|
||||
dc_link_dp_handle_link_loss(link);
|
||||
|
||||
status = false;
|
||||
if (out_link_loss)
|
||||
@ -4119,6 +4142,11 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd
|
||||
return status;
|
||||
}
|
||||
|
||||
bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss)
|
||||
{
|
||||
return handle_hpd_rx_irq(link, out_hpd_irq_dpcd_data, out_link_loss, false, NULL);
|
||||
}
|
||||
|
||||
/*query dpcd for version and mst cap addresses*/
|
||||
bool is_mst_supported(struct dc_link *link)
|
||||
{
|
||||
|
@ -315,6 +315,9 @@ bool dc_link_wait_for_t12(struct dc_link *link);
|
||||
enum dc_status read_hpd_rx_irq_data(
|
||||
struct dc_link *link,
|
||||
union hpd_irq_data *irq_data);
|
||||
void dc_link_dp_handle_automated_test(struct dc_link *link);
|
||||
void dc_link_dp_handle_link_loss(struct dc_link *link);
|
||||
bool dc_link_dp_allow_hpd_rx_irq(const struct dc_link *link);
|
||||
|
||||
struct dc_sink_init_data;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user