diff options
author | Fangzhi Zuo <Jerry.Zuo@amd.com> | 2021-08-03 18:46:00 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2021-09-01 16:55:10 -0400 |
commit | f01ee019586220c86f238263a4fbde6e72085e11 (patch) | |
tree | 7cc06dedf7dbae7cec4f779cfd9a393d1eef2f9f /drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c | |
parent | drm/amd/display: Add DP 2.0 BIOS and DMUB Support (diff) | |
download | linux-dev-f01ee019586220c86f238263a4fbde6e72085e11.tar.xz linux-dev-f01ee019586220c86f238263a4fbde6e72085e11.zip |
drm/amd/display: Add DP 2.0 SST DC Support
1. Retrieve 128/132b link cap.
2. 128/132b link training and payload allocation.
3. UHBR10 link rate support.
[squash in warning fixes - Alex]
Signed-off-by: Fangzhi Zuo <Jerry.Zuo@amd.com>
Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c | 315 |
1 files changed, 299 insertions, 16 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c index 9c51cd09dcf1..29b9c128c87c 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c @@ -17,6 +17,7 @@ #include "link_enc_cfg.h" #include "clk_mgr.h" #include "inc/link_dpcd.h" +#include "dccg.h" static uint8_t convert_to_count(uint8_t lttpr_repeater_count) { @@ -111,12 +112,37 @@ void dp_enable_link_phy( link->cur_link_settings = *link_settings; +#if defined(CONFIG_DRM_AMD_DC_DCN) + if (dp_get_link_encoding_format(link_settings) == DP_128b_132b_ENCODING) { + /* TODO - DP2.0 HW: notify link rate change here */ + } else if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) { + if (dc->clk_mgr->funcs->notify_link_rate_change) + dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link); + } +#else if (dc->clk_mgr->funcs->notify_link_rate_change) dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link); - +#endif if (dmcu != NULL && dmcu->funcs->lock_phy) dmcu->funcs->lock_phy(dmcu); +#if defined(CONFIG_DRM_AMD_DC_DCN) + if (dp_get_link_encoding_format(link_settings) == DP_128b_132b_ENCODING) { + enable_dp_hpo_output(link, link_settings); + } else if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) { + if (dc_is_dp_sst_signal(signal)) { + link_enc->funcs->enable_dp_output( + link_enc, + link_settings, + clock_source); + } else { + link_enc->funcs->enable_dp_mst_output( + link_enc, + link_settings, + clock_source); + } + } +#else if (dc_is_dp_sst_signal(signal)) { link_enc->funcs->enable_dp_output( link_enc, @@ -128,7 +154,7 @@ void dp_enable_link_phy( link_settings, clock_source); } - +#endif if (dmcu != NULL && dmcu->funcs->unlock_phy) dmcu->funcs->unlock_phy(dmcu); @@ -206,6 +232,9 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal) { struct dc *dc = link->ctx->dc; struct dmcu *dmcu = dc->res_pool->dmcu; +#if defined(CONFIG_DRM_AMD_DC_DCN) + struct hpo_dp_link_encoder *hpo_link_enc = link->hpo_dp_link_enc; +#endif struct link_encoder *link_enc; /* Link should always be assigned encoder when en-/disabling. */ @@ -221,14 +250,28 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal) if (signal == SIGNAL_TYPE_EDP) { if (link->dc->hwss.edp_backlight_control) link->dc->hwss.edp_backlight_control(link, false); +#if defined(CONFIG_DRM_AMD_DC_DCN) + if (dp_get_link_encoding_format(&link->cur_link_settings) == DP_128b_132b_ENCODING) + disable_dp_hpo_output(link, signal); + else + link_enc->funcs->disable_output(link_enc, signal); +#else link_enc->funcs->disable_output(link_enc, signal); +#endif link->dc->hwss.edp_power_control(link, false); } else { if (dmcu != NULL && dmcu->funcs->lock_phy) dmcu->funcs->lock_phy(dmcu); +#if defined(CONFIG_DRM_AMD_DC_DCN) + if (dp_get_link_encoding_format(&link->cur_link_settings) == DP_128b_132b_ENCODING && + hpo_link_enc) + disable_dp_hpo_output(link, signal); + else + link_enc->funcs->disable_output(link_enc, signal); +#else link_enc->funcs->disable_output(link_enc, signal); - +#endif if (dmcu != NULL && dmcu->funcs->unlock_phy) dmcu->funcs->unlock_phy(dmcu); } @@ -273,6 +316,14 @@ bool dp_set_hw_training_pattern( case DP_TRAINING_PATTERN_SEQUENCE_4: test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4; break; +#if defined(CONFIG_DRM_AMD_DC_DCN) + case DP_128b_132b_TPS1: + test_pattern = DP_TEST_PATTERN_128b_132b_TPS1_TRAINING_MODE; + break; + case DP_128b_132b_TPS2: + test_pattern = DP_TEST_PATTERN_128b_132b_TPS2_TRAINING_MODE; + break; +#endif default: break; } @@ -282,6 +333,10 @@ bool dp_set_hw_training_pattern( return true; } +#if defined(CONFIG_DRM_AMD_DC_DCN) +#define DC_LOGGER \ + link->ctx->logger +#endif void dp_set_hw_lane_settings( struct dc_link *link, const struct link_training_settings *link_settings, @@ -293,7 +348,20 @@ void dp_set_hw_lane_settings( return; /* call Encoder to set lane settings */ +#if defined(CONFIG_DRM_AMD_DC_DCN) + if (dp_get_link_encoding_format(&link_settings->link_settings) == + DP_128b_132b_ENCODING) { + link->hpo_dp_link_enc->funcs->set_ffe( + link->hpo_dp_link_enc, + &link_settings->link_settings, + link_settings->lane_settings[0].FFE_PRESET.raw); + } else if (dp_get_link_encoding_format(&link_settings->link_settings) + == DP_8b_10b_ENCODING) { + encoder->funcs->dp_set_lane_settings(encoder, link_settings); + } +#else encoder->funcs->dp_set_lane_settings(encoder, link_settings); +#endif } void dp_set_hw_test_pattern( @@ -304,6 +372,9 @@ void dp_set_hw_test_pattern( { struct encoder_set_dp_phy_pattern_param pattern_param = {0}; struct link_encoder *encoder; +#if defined(CONFIG_DRM_AMD_DC_DCN) + enum dp_link_encoding link_encoding_format = dp_get_link_encoding_format(&link->cur_link_settings); +#endif /* Access link encoder based on whether it is statically * or dynamically assigned to a link. @@ -319,8 +390,27 @@ void dp_set_hw_test_pattern( pattern_param.custom_pattern_size = custom_pattern_size; pattern_param.dp_panel_mode = dp_get_panel_mode(link); +#if defined(CONFIG_DRM_AMD_DC_DCN) + switch (link_encoding_format) { + case DP_128b_132b_ENCODING: + link->hpo_dp_link_enc->funcs->set_link_test_pattern( + link->hpo_dp_link_enc, &pattern_param); + break; + case DP_8b_10b_ENCODING: + ASSERT(encoder); + encoder->funcs->dp_set_phy_pattern(encoder, &pattern_param); + break; + default: + DC_LOG_ERROR("%s: Unknown link encoding format.", __func__); + break; + } +#else encoder->funcs->dp_set_phy_pattern(encoder, &pattern_param); +#endif } +#if defined(CONFIG_DRM_AMD_DC_DCN) +#undef DC_LOGGER +#endif void dp_retrain_link_dp_test(struct dc_link *link, struct dc_link_settings *link_setting, @@ -468,7 +558,12 @@ void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED; /* Enable DSC in encoder */ +#if defined(CONFIG_DRM_AMD_DC_DCN) + if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) + && !is_dp_128b_132b_signal(pipe_ctx)) { +#else if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { +#endif DC_LOG_DSC("Setting stream encoder DSC config for engine %d:", (int)pipe_ctx->stream_res.stream_enc->id); dsc_optc_config_log(dsc, &dsc_optc_cfg); pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(pipe_ctx->stream_res.stream_enc, @@ -495,13 +590,21 @@ void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) /* disable DSC in stream encoder */ if (dc_is_dp_signal(stream->signal)) { - if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { - pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config( - pipe_ctx->stream_res.stream_enc, - OPTC_DSC_DISABLED, 0, 0); - pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet( - pipe_ctx->stream_res.stream_enc, false, NULL); - } +#if defined(CONFIG_DRM_AMD_DC_DCN) + if (is_dp_128b_132b_signal(pipe_ctx)) + pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet( + pipe_ctx->stream_res.hpo_dp_stream_enc, + false, + NULL); + else +#endif + if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { + pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config( + pipe_ctx->stream_res.stream_enc, + OPTC_DSC_DISABLED, 0, 0); + pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet( + pipe_ctx->stream_res.stream_enc, false, NULL); + } } /* disable DSC block */ @@ -562,16 +665,32 @@ bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable) dsc->funcs->dsc_get_packed_pps(dsc, &dsc_cfg, &dsc_packed_pps[0]); if (dc_is_dp_signal(stream->signal)) { DC_LOG_DSC("Setting stream encoder DSC PPS SDP for engine %d\n", (int)pipe_ctx->stream_res.stream_enc->id); - pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet( - pipe_ctx->stream_res.stream_enc, - true, - &dsc_packed_pps[0]); +#if defined(CONFIG_DRM_AMD_DC_DCN) + if (is_dp_128b_132b_signal(pipe_ctx)) + pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet( + pipe_ctx->stream_res.hpo_dp_stream_enc, + true, + &dsc_packed_pps[0]); + else +#endif + pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet( + pipe_ctx->stream_res.stream_enc, + true, + &dsc_packed_pps[0]); } } else { /* disable DSC PPS in stream encoder */ if (dc_is_dp_signal(stream->signal)) { - pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet( - pipe_ctx->stream_res.stream_enc, false, NULL); +#if defined(CONFIG_DRM_AMD_DC_DCN) + if (is_dp_128b_132b_signal(pipe_ctx)) + pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet( + pipe_ctx->stream_res.hpo_dp_stream_enc, + false, + NULL); + else +#endif + pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet( + pipe_ctx->stream_res.stream_enc, false, NULL); } } @@ -593,3 +712,167 @@ bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx) return true; } +#if defined(CONFIG_DRM_AMD_DC_DCN) +#undef DC_LOGGER +#define DC_LOGGER \ + link->ctx->logger + +static enum phyd32clk_clock_source get_phyd32clk_src(struct dc_link *link) +{ + switch (link->link_enc->transmitter) { + case TRANSMITTER_UNIPHY_A: + return PHYD32CLKA; + case TRANSMITTER_UNIPHY_B: + return PHYD32CLKB; + case TRANSMITTER_UNIPHY_C: + return PHYD32CLKC; + case TRANSMITTER_UNIPHY_D: + return PHYD32CLKD; + case TRANSMITTER_UNIPHY_E: + return PHYD32CLKE; + default: + return PHYD32CLKA; + } +} + +void enable_dp_hpo_output(struct dc_link *link, const struct dc_link_settings *link_settings) +{ + const struct dc *dc = link->dc; + enum phyd32clk_clock_source phyd32clk; + + /* Enable PHY PLL at target bit rate + * UHBR10 = 10Gbps (SYMCLK32 = 312.5MHz) + * UBR13.5 = 13.5Gbps (SYMCLK32 = 421.875MHz) + * UHBR20 = 20Gbps (SYMCLK32 = 625MHz) + */ + if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { + switch (link_settings->link_rate) { + case LINK_RATE_UHBR10: + dm_set_phyd32clk(dc->ctx, 312500); + break; + case LINK_RATE_UHBR13_5: + dm_set_phyd32clk(dc->ctx, 412875); + break; + case LINK_RATE_UHBR20: + dm_set_phyd32clk(dc->ctx, 625000); + break; + default: + return; + } + } else { + /* DP2.0 HW: call transmitter control to enable PHY */ + link->hpo_dp_link_enc->funcs->enable_link_phy( + link->hpo_dp_link_enc, + link_settings, + link->link_enc->transmitter); + } + + /* DCCG muxing and DTBCLK DTO */ + if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { + dc->res_pool->dccg->funcs->set_physymclk( + dc->res_pool->dccg, + link->link_enc_hw_inst, + PHYSYMCLK_FORCE_SRC_PHYD32CLK, + true); + + phyd32clk = get_phyd32clk_src(link); + dc->res_pool->dccg->funcs->enable_symclk32_le( + dc->res_pool->dccg, + link->hpo_dp_link_enc->inst, + phyd32clk); + link->hpo_dp_link_enc->funcs->link_enable( + link->hpo_dp_link_enc, + link_settings->lane_count); + } +} + +void disable_dp_hpo_output(struct dc_link *link, enum signal_type signal) +{ + const struct dc *dc = link->dc; + + link->hpo_dp_link_enc->funcs->link_disable(link->hpo_dp_link_enc); + + if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { + dc->res_pool->dccg->funcs->disable_symclk32_le( + dc->res_pool->dccg, + link->hpo_dp_link_enc->inst); + + dc->res_pool->dccg->funcs->set_physymclk( + dc->res_pool->dccg, + link->link_enc_hw_inst, + PHYSYMCLK_FORCE_SRC_SYMCLK, + false); + + dm_set_phyd32clk(dc->ctx, 0); + } else { + /* DP2.0 HW: call transmitter control to disable PHY */ + link->hpo_dp_link_enc->funcs->disable_link_phy( + link->hpo_dp_link_enc, + signal); + } +} + +void setup_dp_hpo_stream(struct pipe_ctx *pipe_ctx, bool enable) +{ + struct dc_stream_state *stream = pipe_ctx->stream; + struct dc *dc = pipe_ctx->stream->ctx->dc; + struct pipe_ctx *odm_pipe; + int odm_combine_num_segments = 1; + enum phyd32clk_clock_source phyd32clk; + + if (enable) { + for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) + odm_combine_num_segments++; + + dc->res_pool->dccg->funcs->set_dpstreamclk( + dc->res_pool->dccg, + DTBCLK0, + pipe_ctx->stream_res.tg->inst); + + phyd32clk = get_phyd32clk_src(stream->link); + dc->res_pool->dccg->funcs->enable_symclk32_se( + dc->res_pool->dccg, + pipe_ctx->stream_res.hpo_dp_stream_enc->inst, + phyd32clk); + + dc->res_pool->dccg->funcs->set_dtbclk_dto( + dc->res_pool->dccg, + pipe_ctx->stream_res.tg->inst, + stream->phy_pix_clk, + odm_combine_num_segments, + &stream->timing); + } else { + dc->res_pool->dccg->funcs->set_dtbclk_dto( + dc->res_pool->dccg, + pipe_ctx->stream_res.tg->inst, + 0, + 0, + &stream->timing); + dc->res_pool->dccg->funcs->disable_symclk32_se( + dc->res_pool->dccg, + pipe_ctx->stream_res.hpo_dp_stream_enc->inst); + dc->res_pool->dccg->funcs->set_dpstreamclk( + dc->res_pool->dccg, + REFCLK, + pipe_ctx->stream_res.tg->inst); + } +} + +void reset_dp_hpo_stream_encoders_for_link(struct dc_link *link) +{ + const struct dc *dc = link->dc; + struct dc_state *state = dc->current_state; + uint8_t i; + + for (i = 0; i < MAX_PIPES; i++) { + if (state->res_ctx.pipe_ctx[i].stream_res.hpo_dp_stream_enc && + state->res_ctx.pipe_ctx[i].stream && + state->res_ctx.pipe_ctx[i].stream->link == link && + !state->res_ctx.pipe_ctx[i].stream->dpms_off) { + setup_dp_hpo_stream(&state->res_ctx.pipe_ctx[i], false); + } + } +} + +#undef DC_LOGGER +#endif |