Commit 2da3556c authored by Saaem Rizvi's avatar Saaem Rizvi Committed by Alex Deucher

drm/amd/display: Trigger DIO FIFO resync on commit streams for DCN32

[WHY and HOW]
Currently, on DCN32 we have an old workaround to resolve a DIO FIFO
speed issue when writing to the OTG DIVIDER register. However, this
workaround is not safe as we should be applying the DIO FIFO rampup
logic when the OTG re disabled along with the encoders. This new
workaround accounts for this. If the workaround sequence is incorrect,
like it is was, there is a chance we might hang. this new
workaround was first implemented in DCN314.
Reviewed-by: default avatarAlvin Lee <alvin.lee2@amd.com>
Acked-by: default avatarTom Chung <chiahsuan.chung@amd.com>
Signed-off-by: default avatarSaaem Rizvi <syedsaaem.rizvi@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 26818260
......@@ -412,6 +412,8 @@ void dcn314_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc
hws->ctx->dc->res_pool->dccg->funcs->trigger_dio_fifo_resync(hws->ctx->dc->res_pool->dccg);
for (i = 0; i < dc->res_pool->pipe_count; i++) {
pipe = &dc->current_state->res_ctx.pipe_ctx[i];
if (otg_disabled[i])
pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
}
......
......@@ -42,18 +42,14 @@
#define DC_LOGGER \
dccg->ctx->logger
/* This function is a workaround for writing to OTG_PIXEL_RATE_DIV
* without the probability of causing a DIG FIFO error.
*/
static void dccg32_wait_for_dentist_change_done(
static void dccg32_trigger_dio_fifo_resync(
struct dccg *dccg)
{
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
uint32_t dispclk_rdivider_value = 0;
uint32_t dentist_dispclk_value = REG_READ(DENTIST_DISPCLK_CNTL);
REG_WRITE(DENTIST_DISPCLK_CNTL, dentist_dispclk_value);
REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 2000);
REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_RDIVIDER, &dispclk_rdivider_value);
REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, dispclk_rdivider_value);
}
static void dccg32_get_pixel_rate_div(
......@@ -124,29 +120,21 @@ static void dccg32_set_pixel_rate_div(
REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
OTG0_PIXEL_RATE_DIVK1, k1,
OTG0_PIXEL_RATE_DIVK2, k2);
dccg32_wait_for_dentist_change_done(dccg);
break;
case 1:
REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
OTG1_PIXEL_RATE_DIVK1, k1,
OTG1_PIXEL_RATE_DIVK2, k2);
dccg32_wait_for_dentist_change_done(dccg);
break;
case 2:
REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
OTG2_PIXEL_RATE_DIVK1, k1,
OTG2_PIXEL_RATE_DIVK2, k2);
dccg32_wait_for_dentist_change_done(dccg);
break;
case 3:
REG_UPDATE_2(OTG_PIXEL_RATE_DIV,
OTG3_PIXEL_RATE_DIVK1, k1,
OTG3_PIXEL_RATE_DIVK2, k2);
dccg32_wait_for_dentist_change_done(dccg);
break;
default:
BREAK_TO_DEBUGGER();
......@@ -352,6 +340,7 @@ static const struct dccg_funcs dccg32_funcs = {
.otg_add_pixel = dccg32_otg_add_pixel,
.otg_drop_pixel = dccg32_otg_drop_pixel,
.set_pixel_rate_div = dccg32_set_pixel_rate_div,
.trigger_dio_fifo_resync = dccg32_trigger_dio_fifo_resync,
};
struct dccg *dccg32_create(
......
......@@ -112,8 +112,9 @@
DCCG_SF(DTBCLK_P_CNTL, DTBCLK_P3_EN, mask_sh),\
DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO_SEL, mask_sh),\
DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL, mask_sh),\
DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh)
DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh),\
DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_RDIVIDER, mask_sh),\
DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh)
struct dccg *dccg32_create(
struct dc_context *ctx,
......
......@@ -1175,6 +1175,35 @@ void dcn32_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx)
pix_per_cycle);
}
void dcn32_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context)
{
uint8_t i;
struct pipe_ctx *pipe = NULL;
bool otg_disabled[MAX_PIPES] = {false};
for (i = 0; i < dc->res_pool->pipe_count; i++) {
pipe = &dc->current_state->res_ctx.pipe_ctx[i];
if (pipe->top_pipe || pipe->prev_odm_pipe)
continue;
if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal))) {
pipe->stream_res.tg->funcs->disable_crtc(pipe->stream_res.tg);
reset_sync_context_for_pipe(dc, context, i);
otg_disabled[i] = true;
}
}
hws->ctx->dc->res_pool->dccg->funcs->trigger_dio_fifo_resync(hws->ctx->dc->res_pool->dccg);
for (i = 0; i < dc->res_pool->pipe_count; i++) {
pipe = &dc->current_state->res_ctx.pipe_ctx[i];
if (otg_disabled[i])
pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
}
}
void dcn32_unblank_stream(struct pipe_ctx *pipe_ctx,
struct dc_link_settings *link_settings)
{
......
......@@ -75,6 +75,8 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign
void dcn32_set_pixels_per_cycle(struct pipe_ctx *pipe_ctx);
void dcn32_resync_fifo_dccg_dio(struct dce_hwseq *hws, struct dc *dc, struct dc_state *context);
void dcn32_subvp_pipe_control_lock(struct dc *dc,
struct dc_state *context,
bool lock,
......
......@@ -153,6 +153,7 @@ static const struct hwseq_private_funcs dcn32_private_funcs = {
.update_mall_sel = dcn32_update_mall_sel,
.calculate_dccg_k1_k2_values = dcn32_calculate_dccg_k1_k2_values,
.set_pixels_per_cycle = dcn32_set_pixels_per_cycle,
.resync_fifo_dccg_dio = dcn32_resync_fifo_dccg_dio,
.is_dp_dig_pixel_rate_div_policy = dcn32_is_dp_dig_pixel_rate_div_policy,
};
......
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