diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3843-drm-amd-display-enable-single-dp-seamless-boot.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3843-drm-amd-display-enable-single-dp-seamless-boot.patch | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3843-drm-amd-display-enable-single-dp-seamless-boot.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3843-drm-amd-display-enable-single-dp-seamless-boot.patch new file mode 100644 index 00000000..1105730a --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3843-drm-amd-display-enable-single-dp-seamless-boot.patch @@ -0,0 +1,255 @@ +From 3fd571fd36708e2dd7c6873038e113251468d836 Mon Sep 17 00:00:00 2001 +From: Martin Leung <martin.leung@amd.com> +Date: Fri, 16 Aug 2019 17:26:23 -0400 +Subject: [PATCH 3843/4256] drm/amd/display: enable single dp seamless boot + +[why] +seamless boot didn't work for non edp's before + +[how] +removed edp-specific code, made dp read uefi-set link settings. Also fixed +a hubbub code line to be consistent with usage of function. + +Signed-off-by: Martin Leung <martin.leung@amd.com> +Reviewed-by: Jun Lei <Jun.Lei@amd.com> +Acked-by: Anthony Koo <Anthony.Koo@amd.com> +Acked-by: Leo Li <sunpeng.li@amd.com> +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 30 +++++----- + drivers/gpu/drm/amd/display/dc/core/dc_link.c | 57 ++++++++++++------- + .../gpu/drm/amd/display/dc/core/dc_resource.c | 26 ++++----- + .../drm/amd/display/dc/dcn20/dcn20_hubbub.c | 5 +- + 4 files changed, 71 insertions(+), 47 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index ffa6544f1e25..e5fd65f634ac 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -983,29 +983,33 @@ bool dc_validate_seamless_boot_timing(const struct dc *dc, + { + struct timing_generator *tg; + struct dc_link *link = sink->link; +- unsigned int enc_inst, tg_inst; ++ unsigned int enc_inst, tg_inst, i; ++ ++ // Seamless port only support single DP and EDP so far ++ if (sink->sink_signal != SIGNAL_TYPE_DISPLAY_PORT && ++ sink->sink_signal != SIGNAL_TYPE_EDP) ++ return false; + + /* Check for enabled DIG to identify enabled display */ + if (!link->link_enc->funcs->is_dig_enabled(link->link_enc)) + return false; + +- /* Check for which front end is used by this encoder. +- * Note the inst is 1 indexed, where 0 is undefined. +- * Note that DIG_FE can source from different OTG but our +- * current implementation always map 1-to-1, so this code makes +- * the same assumption and doesn't check OTG source. +- */ + enc_inst = link->link_enc->funcs->get_dig_frontend(link->link_enc); + +- /* Instance should be within the range of the pool */ +- if (enc_inst >= dc->res_pool->pipe_count) ++ if (enc_inst == ENGINE_ID_UNKNOWN) + return false; + +- if (enc_inst >= dc->res_pool->stream_enc_count) +- return false; ++ for (i = 0; i < dc->res_pool->stream_enc_count; i++) { ++ if (dc->res_pool->stream_enc[i]->id == enc_inst) { ++ tg_inst = dc->res_pool->stream_enc[i]->funcs->dig_source_otg( ++ dc->res_pool->stream_enc[i]); ++ break; ++ } ++ } + +- tg_inst = dc->res_pool->stream_enc[enc_inst]->funcs->dig_source_otg( +- dc->res_pool->stream_enc[enc_inst]); ++ // tg_inst not found ++ if (i == dc->res_pool->stream_enc_count) ++ return false; + + if (tg_inst >= dc->res_pool->timing_generator_count) + return false; +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c +index a20310feb352..66758033757d 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c +@@ -517,7 +517,7 @@ static void link_disconnect_remap(struct dc_sink *prev_sink, struct dc_link *lin + } + + +-static void read_edp_current_link_settings_on_detect(struct dc_link *link) ++static void read_current_link_settings_on_detect(struct dc_link *link) + { + union lane_count_set lane_count_set = { {0} }; + uint8_t link_bw_set; +@@ -552,17 +552,23 @@ static void read_edp_current_link_settings_on_detect(struct dc_link *link) + &link_bw_set, sizeof(link_bw_set)); + + if (link_bw_set == 0) { +- /* If standard link rates are not being used, +- * Read DPCD 00115h to find the link rate set used +- */ +- core_link_read_dpcd(link, DP_LINK_RATE_SET, +- &link_rate_set, sizeof(link_rate_set)); +- +- if (link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) { +- link->cur_link_settings.link_rate = +- link->dpcd_caps.edp_supported_link_rates[link_rate_set]; +- link->cur_link_settings.link_rate_set = link_rate_set; +- link->cur_link_settings.use_link_rate_set = true; ++ if (link->connector_signal == SIGNAL_TYPE_EDP) { ++ /* If standard link rates are not being used, ++ * Read DPCD 00115h to find the edp link rate set used ++ */ ++ core_link_read_dpcd(link, DP_LINK_RATE_SET, ++ &link_rate_set, sizeof(link_rate_set)); ++ ++ // edp_supported_link_rates_count = 0 for DP ++ if (link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) { ++ link->cur_link_settings.link_rate = ++ link->dpcd_caps.edp_supported_link_rates[link_rate_set]; ++ link->cur_link_settings.link_rate_set = link_rate_set; ++ link->cur_link_settings.use_link_rate_set = true; ++ } ++ } else { ++ // Link Rate not found. Seamless boot may not work. ++ ASSERT(false); + } + } else { + link->cur_link_settings.link_rate = link_bw_set; +@@ -750,6 +756,7 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) + struct dpcd_caps prev_dpcd_caps; + bool same_dpcd = true; + enum dc_connection_type new_connection_type = dc_connection_none; ++ bool perform_dp_seamless_boot = false; + DC_LOGGER_INIT(link->ctx->logger); + + if (dc_is_virtual_signal(link->connector_signal)) +@@ -806,15 +813,15 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) + } + + case SIGNAL_TYPE_EDP: { +- read_edp_current_link_settings_on_detect(link); ++ read_current_link_settings_on_detect(link); + detect_edp_sink_caps(link); +- sink_caps.transaction_type = +- DDC_TRANSACTION_TYPE_I2C_OVER_AUX; ++ sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX; + sink_caps.signal = SIGNAL_TYPE_EDP; + break; + } + + case SIGNAL_TYPE_DISPLAY_PORT: { ++ + /* wa HPD high coming too early*/ + if (link->link_enc->features.flags.bits.DP_IS_USB_C == 1) { + +@@ -868,6 +875,17 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) + return false; + } + ++ // For seamless boot, to skip verify link cap, we read UEFI settings and set them as verified. ++ if (reason == DETECT_REASON_BOOT && ++ dc_ctx->dc->config.power_down_display_on_boot == false && ++ link->link_status.link_active == true) ++ perform_dp_seamless_boot = true; ++ ++ if (perform_dp_seamless_boot) { ++ read_current_link_settings_on_detect(link); ++ link->verified_link_cap = link->reported_link_cap; ++ } ++ + break; + } + +@@ -952,10 +970,11 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) + * two link trainings + */ + +- /* deal with non-mst cases */ +- dp_verify_link_cap_with_retries(link, +- &link->reported_link_cap, +- LINK_TRAINING_MAX_VERIFY_RETRY); ++ // verify link cap for SST non-seamless boot ++ if (!perform_dp_seamless_boot) ++ dp_verify_link_cap_with_retries(link, ++ &link->reported_link_cap, ++ LINK_TRAINING_MAX_VERIFY_RETRY); + } else { + // If edid is the same, then discard new sink and revert back to original sink + if (same_edid) { +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +index 2ae883a248da..af85d6cf4427 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +@@ -1845,28 +1845,28 @@ static int acquire_resource_from_hw_enabled_state( + struct dc_stream_state *stream) + { + struct dc_link *link = stream->link; +- unsigned int inst, tg_inst; ++ unsigned int inst, tg_inst, i; + + /* Check for enabled DIG to identify enabled display */ + if (!link->link_enc->funcs->is_dig_enabled(link->link_enc)) + return -1; + +- /* Check for which front end is used by this encoder. +- * Note the inst is 1 indexed, where 0 is undefined. +- * Note that DIG_FE can source from different OTG but our +- * current implementation always map 1-to-1, so this code makes +- * the same assumption and doesn't check OTG source. +- */ + inst = link->link_enc->funcs->get_dig_frontend(link->link_enc); + +- /* Instance should be within the range of the pool */ +- if (inst >= pool->pipe_count) +- return -1; ++ if (inst == ENGINE_ID_UNKNOWN) ++ return false; + +- if (inst >= pool->stream_enc_count) +- return -1; ++ for (i = 0; i < pool->stream_enc_count; i++) { ++ if (pool->stream_enc[i]->id == inst) { ++ tg_inst = pool->stream_enc[i]->funcs->dig_source_otg( ++ pool->stream_enc[i]); ++ break; ++ } ++ } + +- tg_inst = pool->stream_enc[inst]->funcs->dig_source_otg(pool->stream_enc[inst]); ++ // tg_inst not found ++ if (i == pool->stream_enc_count) ++ return false; + + if (tg_inst >= pool->timing_generator_count) + return false; +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c +index b83c022e2c6f..e0a6e30ac3e1 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c +@@ -588,7 +588,7 @@ static void hubbub2_program_watermarks( + DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz); + REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 180); + +- hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter); ++ hubbub->funcs->allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter); + } + + static const struct hubbub_funcs hubbub2_funcs = { +@@ -600,7 +600,8 @@ static const struct hubbub_funcs hubbub2_funcs = { + .get_dcc_compression_cap = hubbub2_get_dcc_compression_cap, + .wm_read_state = hubbub2_wm_read_state, + .get_dchub_ref_freq = hubbub2_get_dchub_ref_freq, +- .program_watermarks = hubbub2_program_watermarks ++ .program_watermarks = hubbub2_program_watermarks, ++ .allow_self_refresh_control = hubbub1_allow_self_refresh_control + }; + + void hubbub2_construct(struct dcn20_hubbub *hubbub, +-- +2.17.1 + |