Skip to content

Commit f57fa0f

Browse files
Leo Chenalexdeucher
authored andcommitted
drm/amd/display: Add symclk workaround during disable link output
[Why & How] This is originally a change (9c75891) in DCN32 because of the lack of interface to set TX while keeping symclk on. Adding this workaround to DCN314 will resolve the current issue. Fixes: 9c75891 ("drm/amd/display: rework recent update PHY state commit") Reviewed-by: Nicholas Kazlauskas <[email protected]> Acked-by: Alex Hung <[email protected]> Signed-off-by: Leo Chen <[email protected]> Tested-by: Daniel Wheeler <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 58d9b9a commit f57fa0f

File tree

3 files changed

+68
-1
lines changed

3 files changed

+68
-1
lines changed

drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,3 +423,68 @@ void dcn314_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool
423423

424424
PERF_TRACE();
425425
}
426+
static void apply_symclk_on_tx_off_wa(struct dc_link *link)
427+
{
428+
/* There are use cases where SYMCLK is referenced by OTG. For instance
429+
* for TMDS signal, OTG relies SYMCLK even if TX video output is off.
430+
* However current link interface will power off PHY when disabling link
431+
* output. This will turn off SYMCLK generated by PHY. The workaround is
432+
* to identify such case where SYMCLK is still in use by OTG when we
433+
* power off PHY. When this is detected, we will temporarily power PHY
434+
* back on and move PHY's SYMCLK state to SYMCLK_ON_TX_OFF by calling
435+
* program_pix_clk interface. When OTG is disabled, we will then power
436+
* off PHY by calling disable link output again.
437+
*
438+
* In future dcn generations, we plan to rework transmitter control
439+
* interface so that we could have an option to set SYMCLK ON TX OFF
440+
* state in one step without this workaround
441+
*/
442+
443+
struct dc *dc = link->ctx->dc;
444+
struct pipe_ctx *pipe_ctx = NULL;
445+
uint8_t i;
446+
447+
if (link->phy_state.symclk_ref_cnts.otg > 0) {
448+
for (i = 0; i < MAX_PIPES; i++) {
449+
pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
450+
if (pipe_ctx->stream && pipe_ctx->stream->link == link && pipe_ctx->top_pipe == NULL) {
451+
pipe_ctx->clock_source->funcs->program_pix_clk(
452+
pipe_ctx->clock_source,
453+
&pipe_ctx->stream_res.pix_clk_params,
454+
dc->link_srv->dp_get_encoding_format(
455+
&pipe_ctx->link_config.dp_link_settings),
456+
&pipe_ctx->pll_settings);
457+
link->phy_state.symclk_state = SYMCLK_ON_TX_OFF;
458+
break;
459+
}
460+
}
461+
}
462+
}
463+
464+
void dcn314_disable_link_output(struct dc_link *link,
465+
const struct link_resource *link_res,
466+
enum signal_type signal)
467+
{
468+
struct dc *dc = link->ctx->dc;
469+
const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
470+
struct dmcu *dmcu = dc->res_pool->dmcu;
471+
472+
if (signal == SIGNAL_TYPE_EDP &&
473+
link->dc->hwss.edp_backlight_control)
474+
link->dc->hwss.edp_backlight_control(link, false);
475+
else if (dmcu != NULL && dmcu->funcs->lock_phy)
476+
dmcu->funcs->lock_phy(dmcu);
477+
478+
link_hwss->disable_link_output(link, link_res, signal);
479+
link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
480+
/*
481+
* Add the logic to extract BOTH power up and power down sequences
482+
* from enable/disable link output and only call edp panel control
483+
* in enable_link_dp and disable_link_dp once.
484+
*/
485+
if (dmcu != NULL && dmcu->funcs->lock_phy)
486+
dmcu->funcs->unlock_phy(dmcu);
487+
dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
488+
489+
apply_symclk_on_tx_off_wa(link);
490+
}

drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,6 @@ void dcn314_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool
4545

4646
void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool clock_on);
4747

48+
void dcn314_disable_link_output(struct dc_link *link, const struct link_resource *link_res, enum signal_type signal);
49+
4850
#endif /* __DC_HWSS_DCN314_H__ */

drivers/gpu/drm/amd/display/dc/dcn314/dcn314_init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ static const struct hw_sequencer_funcs dcn314_funcs = {
105105
.enable_lvds_link_output = dce110_enable_lvds_link_output,
106106
.enable_tmds_link_output = dce110_enable_tmds_link_output,
107107
.enable_dp_link_output = dce110_enable_dp_link_output,
108-
.disable_link_output = dce110_disable_link_output,
108+
.disable_link_output = dcn314_disable_link_output,
109109
.z10_restore = dcn31_z10_restore,
110110
.z10_save_init = dcn31_z10_save_init,
111111
.set_disp_pattern_generator = dcn30_set_disp_pattern_generator,

0 commit comments

Comments
 (0)