Commit 21878404 authored by Jingwen Zhu's avatar Jingwen Zhu Committed by Alex Deucher

drm/amd/display: avoid disable otg when dig was disabled

[Why]
This is a workaround for an dcn3.1 hang that happens if otg dispclk
is ramped while otg is on and stream enc is off.
But this w/a should not trigger when we have a dig active.

[How]
Avoid disable otg when dig FE/BE FIFO was not switched.
Acked-by: default avatarRodrigo Siqueira <rodrigo.siqueira@amd.com>
Signed-off-by: default avatarJerry Zuo <jerry.zuo@amd.com>
Signed-off-by: default avatarJingwen Zhu <jingwen.zhu@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent c83ecc0b
...@@ -120,7 +120,6 @@ static int dcn35_get_active_display_cnt_wa( ...@@ -120,7 +120,6 @@ static int dcn35_get_active_display_cnt_wa(
return display_count; return display_count;
} }
static void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, static void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context,
bool safe_to_lower, bool disable) bool safe_to_lower, bool disable)
{ {
...@@ -128,14 +127,27 @@ static void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state * ...@@ -128,14 +127,27 @@ static void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *
int i; int i;
for (i = 0; i < dc->res_pool->pipe_count; ++i) { for (i = 0; i < dc->res_pool->pipe_count; ++i) {
struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
struct pipe_ctx *pipe = safe_to_lower struct pipe_ctx *pipe = safe_to_lower
? &context->res_ctx.pipe_ctx[i] ? &context->res_ctx.pipe_ctx[i]
: &dc->current_state->res_ctx.pipe_ctx[i]; : &dc->current_state->res_ctx.pipe_ctx[i];
bool stream_changed_otg_dig_on = false;
if (pipe->top_pipe || pipe->prev_odm_pipe) if (pipe->top_pipe || pipe->prev_odm_pipe)
continue; continue;
stream_changed_otg_dig_on = old_pipe->stream && new_pipe->stream &&
old_pipe->stream != new_pipe->stream &&
old_pipe->stream_res.tg == new_pipe->stream_res.tg &&
new_pipe->stream->link_enc && !new_pipe->stream->dpms_off &&
new_pipe->stream->link->link_enc->funcs->is_dig_enabled &&
new_pipe->stream->link->link_enc->funcs->is_dig_enabled(
new_pipe->stream->link->link_enc) &&
new_pipe->stream_res.stream_enc &&
new_pipe->stream_res.stream_enc->funcs->is_fifo_enabled &&
new_pipe->stream_res.stream_enc->funcs->is_fifo_enabled(new_pipe->stream_res.stream_enc);
if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal) || if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal) ||
!pipe->stream->link_enc)) { !pipe->stream->link_enc) && !stream_changed_otg_dig_on) {
/* This w/a should not trigger when we have a dig active */
if (disable) { if (disable) {
if (pipe->stream_res.tg && pipe->stream_res.tg->funcs->disable_crtc) if (pipe->stream_res.tg && pipe->stream_res.tg->funcs->disable_crtc)
pipe->stream_res.tg->funcs->disable_crtc(pipe->stream_res.tg); pipe->stream_res.tg->funcs->disable_crtc(pipe->stream_res.tg);
......
...@@ -392,6 +392,14 @@ static void enc35_reset_fifo(struct stream_encoder *enc, bool reset) ...@@ -392,6 +392,14 @@ static void enc35_reset_fifo(struct stream_encoder *enc, bool reset)
udelay(10); udelay(10);
} }
static bool enc35_is_fifo_enabled(struct stream_encoder *enc)
{
struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
uint32_t reset_val;
REG_GET(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, &reset_val);
return (reset_val == 0) ? false : true;
}
void enc35_disable_fifo(struct stream_encoder *enc) void enc35_disable_fifo(struct stream_encoder *enc)
{ {
struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
...@@ -465,6 +473,7 @@ static const struct stream_encoder_funcs dcn35_str_enc_funcs = { ...@@ -465,6 +473,7 @@ static const struct stream_encoder_funcs dcn35_str_enc_funcs = {
.set_input_mode = enc314_set_dig_input_mode, .set_input_mode = enc314_set_dig_input_mode,
.enable_fifo = enc35_enable_fifo, .enable_fifo = enc35_enable_fifo,
.disable_fifo = enc35_disable_fifo, .disable_fifo = enc35_disable_fifo,
.is_fifo_enabled = enc35_is_fifo_enabled,
.map_stream_to_link = enc35_stream_encoder_map_to_link, .map_stream_to_link = enc35_stream_encoder_map_to_link,
}; };
......
...@@ -271,6 +271,7 @@ struct stream_encoder_funcs { ...@@ -271,6 +271,7 @@ struct stream_encoder_funcs {
struct stream_encoder *enc, unsigned int pix_per_container); struct stream_encoder *enc, unsigned int pix_per_container);
void (*enable_fifo)(struct stream_encoder *enc); void (*enable_fifo)(struct stream_encoder *enc);
void (*disable_fifo)(struct stream_encoder *enc); void (*disable_fifo)(struct stream_encoder *enc);
bool (*is_fifo_enabled)(struct stream_encoder *enc);
void (*map_stream_to_link)(struct stream_encoder *enc, uint32_t stream_enc_inst, uint32_t link_enc_inst); void (*map_stream_to_link)(struct stream_encoder *enc, uint32_t stream_enc_inst, uint32_t link_enc_inst);
}; };
......
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