drm/amd/display: make firmware info only load once during dc_bios create

Currently every time DC wants to access firmware info we make a call
into VBIOS. This makes no sense as there is nothing that can change
runtime inside fw info and can cause issues when calling unstable
bios during bringup.

This change eliminate this behavior by only calling bios once for fw
info and keeping it stored as part of dc_bios.

Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Reviewed-by: Chris Park <Chris.Park@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Dmytro Laktyushkin 2019-07-12 15:06:06 -04:00 committed by Alex Deucher
parent 0b22632243
commit 9adc8050bf
12 changed files with 36 additions and 79 deletions

View File

@ -2796,8 +2796,6 @@ static const struct dc_vbios_funcs vbios_funcs = {
.get_device_tag = bios_parser_get_device_tag,
.get_firmware_info = bios_parser_get_firmware_info,
.get_spread_spectrum_info = bios_parser_get_spread_spectrum_info,
.get_ss_entry_number = bios_parser_get_ss_entry_number,
@ -2922,6 +2920,7 @@ static bool bios_parser_construct(
dal_bios_parser_init_cmd_tbl_helper(&bp->cmd_helper, dce_version);
bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base);
bp->base.fw_info_valid = bios_parser_get_firmware_info(&bp->base, &bp->base.fw_info) == BP_RESULT_OK;
return true;
}

View File

@ -1881,8 +1881,6 @@ static const struct dc_vbios_funcs vbios_funcs = {
.get_device_tag = bios_parser_get_device_tag,
.get_firmware_info = bios_parser_get_firmware_info,
.get_spread_spectrum_info = bios_parser_get_spread_spectrum_info,
.get_ss_entry_number = bios_parser_get_ss_entry_number,
@ -1998,6 +1996,7 @@ static bool bios_parser_construct(
dal_bios_parser_init_cmd_tbl_helper2(&bp->cmd_helper, dce_version);
bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base);
bp->base.fw_info_valid = bios_parser_get_firmware_info(&bp->base, &bp->base.fw_info) == BP_RESULT_OK;
return true;
}

View File

@ -273,18 +273,12 @@ static void dce_clock_read_integrated_info(struct clk_mgr_internal *clk_mgr_dce)
{
struct dc_debug_options *debug = &clk_mgr_dce->base.ctx->dc->debug;
struct dc_bios *bp = clk_mgr_dce->base.ctx->dc_bios;
struct integrated_info info = { { { 0 } } };
struct dc_firmware_info fw_info = { { 0 } };
int i;
if (bp->integrated_info)
info = *bp->integrated_info;
clk_mgr_dce->dentist_vco_freq_khz = info.dentist_vco_freq;
clk_mgr_dce->dentist_vco_freq_khz = bp->integrated_info->dentist_vco_freq;
if (clk_mgr_dce->dentist_vco_freq_khz == 0) {
bp->funcs->get_firmware_info(bp, &fw_info);
clk_mgr_dce->dentist_vco_freq_khz =
fw_info.smu_gpu_pll_output_freq;
clk_mgr_dce->dentist_vco_freq_khz = bp->fw_info.smu_gpu_pll_output_freq;
if (clk_mgr_dce->dentist_vco_freq_khz == 0)
clk_mgr_dce->dentist_vco_freq_khz = 3600000;
}
@ -317,9 +311,10 @@ static void dce_clock_read_integrated_info(struct clk_mgr_internal *clk_mgr_dce)
/*Do not allow bad VBIOS/SBIOS to override with invalid values,
* check for > 100MHz*/
if (info.disp_clk_voltage[i].max_supported_clk >= 100000)
clk_mgr_dce->max_clks_by_state[clk_state].display_clk_khz =
info.disp_clk_voltage[i].max_supported_clk;
if (bp->integrated_info)
if (bp->integrated_info->disp_clk_voltage[i].max_supported_clk >= 100000)
clk_mgr_dce->max_clks_by_state[clk_state].display_clk_khz =
bp->integrated_info->disp_clk_voltage[i].max_supported_clk;
}
if (!debug->disable_dfs_bypass && bp->integrated_info)

View File

@ -246,7 +246,6 @@ void rv1_clk_mgr_construct(struct dc_context *ctx, struct clk_mgr_internal *clk_
{
struct dc_debug_options *debug = &ctx->dc->debug;
struct dc_bios *bp = ctx->dc_bios;
struct dc_firmware_info fw_info = { { 0 } };
clk_mgr->base.ctx = ctx;
clk_mgr->pp_smu = pp_smu;
@ -262,9 +261,8 @@ void rv1_clk_mgr_construct(struct dc_context *ctx, struct clk_mgr_internal *clk_
if (bp->integrated_info)
clk_mgr->dentist_vco_freq_khz = bp->integrated_info->dentist_vco_freq;
if (clk_mgr->dentist_vco_freq_khz == 0) {
bp->funcs->get_firmware_info(bp, &fw_info);
clk_mgr->dentist_vco_freq_khz = fw_info.smu_gpu_pll_output_freq;
if (bp->fw_info_valid && clk_mgr->dentist_vco_freq_khz == 0) {
clk_mgr->dentist_vco_freq_khz = bp->fw_info.smu_gpu_pll_output_freq;
if (clk_mgr->dentist_vco_freq_khz == 0)
clk_mgr->dentist_vco_freq_khz = 3600000;
}

View File

@ -173,12 +173,9 @@ struct resource_pool *dc_create_resource_pool(struct dc *dc,
break;
}
if (res_pool != NULL) {
struct dc_firmware_info fw_info = { { 0 } };
if (dc->ctx->dc_bios->funcs->get_firmware_info(dc->ctx->dc_bios,
&fw_info) == BP_RESULT_OK) {
if (dc->ctx->dc_bios->fw_info_valid) {
res_pool->ref_clocks.xtalin_clock_inKhz =
fw_info.pll_info.crystal_frequency;
dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
/* initialize with firmware data first, no all
* ASIC have DCCG SW component. FPGA or
* simulation need initialization of

View File

@ -61,9 +61,6 @@ struct dc_vbios_funcs {
struct graphics_object_id connector_object_id,
uint32_t device_tag_index,
struct connector_device_tag_info *info);
enum bp_result (*get_firmware_info)(
struct dc_bios *bios,
struct dc_firmware_info *info);
enum bp_result (*get_spread_spectrum_info)(
struct dc_bios *bios,
enum as_signal_type signal,
@ -152,6 +149,8 @@ struct dc_bios {
struct dc_context *ctx;
const struct bios_registers *regs;
struct integrated_info *integrated_info;
struct dc_firmware_info fw_info;
bool fw_info_valid;
};
#endif /* DC_BIOS_TYPES_H */

View File

@ -1234,37 +1234,35 @@ static bool calc_pll_max_vco_construct(
struct calc_pll_clock_source_init_data *init_data)
{
uint32_t i;
struct dc_firmware_info fw_info = { { 0 } };
struct dc_firmware_info *fw_info = &init_data->bp->fw_info;
if (calc_pll_cs == NULL ||
init_data == NULL ||
init_data->bp == NULL)
return false;
if (init_data->bp->funcs->get_firmware_info(
init_data->bp,
&fw_info) != BP_RESULT_OK)
if (init_data->bp->fw_info_valid)
return false;
calc_pll_cs->ctx = init_data->ctx;
calc_pll_cs->ref_freq_khz = fw_info.pll_info.crystal_frequency;
calc_pll_cs->ref_freq_khz = fw_info->pll_info.crystal_frequency;
calc_pll_cs->min_vco_khz =
fw_info.pll_info.min_output_pxl_clk_pll_frequency;
fw_info->pll_info.min_output_pxl_clk_pll_frequency;
calc_pll_cs->max_vco_khz =
fw_info.pll_info.max_output_pxl_clk_pll_frequency;
fw_info->pll_info.max_output_pxl_clk_pll_frequency;
if (init_data->max_override_input_pxl_clk_pll_freq_khz != 0)
calc_pll_cs->max_pll_input_freq_khz =
init_data->max_override_input_pxl_clk_pll_freq_khz;
else
calc_pll_cs->max_pll_input_freq_khz =
fw_info.pll_info.max_input_pxl_clk_pll_frequency;
fw_info->pll_info.max_input_pxl_clk_pll_frequency;
if (init_data->min_override_input_pxl_clk_pll_freq_khz != 0)
calc_pll_cs->min_pll_input_freq_khz =
init_data->min_override_input_pxl_clk_pll_freq_khz;
else
calc_pll_cs->min_pll_input_freq_khz =
fw_info.pll_info.min_input_pxl_clk_pll_frequency;
fw_info->pll_info.min_input_pxl_clk_pll_frequency;
calc_pll_cs->min_pix_clock_pll_post_divider =
init_data->min_pix_clk_pll_post_divider;
@ -1316,7 +1314,6 @@ bool dce110_clk_src_construct(
const struct dce110_clk_src_shift *cs_shift,
const struct dce110_clk_src_mask *cs_mask)
{
struct dc_firmware_info fw_info = { { 0 } };
struct calc_pll_clock_source_init_data calc_pll_cs_init_data_hdmi;
struct calc_pll_clock_source_init_data calc_pll_cs_init_data;
@ -1329,14 +1326,12 @@ bool dce110_clk_src_construct(
clk_src->cs_shift = cs_shift;
clk_src->cs_mask = cs_mask;
if (clk_src->bios->funcs->get_firmware_info(
clk_src->bios, &fw_info) != BP_RESULT_OK) {
if (!clk_src->bios->fw_info_valid) {
ASSERT_CRITICAL(false);
goto unexpected_failure;
}
clk_src->ext_clk_khz =
fw_info.external_clock_source_frequency_for_dp;
clk_src->ext_clk_khz = clk_src->bios->fw_info.external_clock_source_frequency_for_dp;
/* structure normally used with PLL ranges from ATOMBIOS; DS on by default */
calc_pll_cs_init_data.bp = bios;
@ -1376,7 +1371,7 @@ bool dce110_clk_src_construct(
FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM;
calc_pll_cs_init_data_hdmi.ctx = ctx;
clk_src->ref_freq_khz = fw_info.pll_info.crystal_frequency;
clk_src->ref_freq_khz = clk_src->bios->fw_info.pll_info.crystal_frequency;
if (clk_src->base.id == CLOCK_SOURCE_ID_EXTERNAL)
return true;
@ -1419,8 +1414,6 @@ bool dce112_clk_src_construct(
const struct dce110_clk_src_shift *cs_shift,
const struct dce110_clk_src_mask *cs_mask)
{
struct dc_firmware_info fw_info = { { 0 } };
clk_src->base.ctx = ctx;
clk_src->bios = bios;
clk_src->base.id = id;
@ -1430,13 +1423,12 @@ bool dce112_clk_src_construct(
clk_src->cs_shift = cs_shift;
clk_src->cs_mask = cs_mask;
if (clk_src->bios->funcs->get_firmware_info(
clk_src->bios, &fw_info) != BP_RESULT_OK) {
if (!clk_src->bios->fw_info_valid) {
ASSERT_CRITICAL(false);
return false;
}
clk_src->ext_clk_khz = fw_info.external_clock_source_frequency_for_dp;
clk_src->ext_clk_khz = clk_src->bios->fw_info.external_clock_source_frequency_for_dp;
return true;
}

View File

@ -99,17 +99,6 @@ static uint32_t get_hw_buffer_available_size(
dce_i2c_hw->buffer_used_bytes;
}
uint32_t get_reference_clock(
struct dc_bios *bios)
{
struct dc_firmware_info info = { { 0 } };
if (bios->funcs->get_firmware_info(bios, &info) != BP_RESULT_OK)
return 0;
return info.pll_info.crystal_frequency;
}
static uint32_t get_speed(
const struct dce_i2c_hw *dce_i2c_hw)
{
@ -632,7 +621,7 @@ void dce_i2c_hw_construct(
{
dce_i2c_hw->ctx = ctx;
dce_i2c_hw->engine_id = engine_id;
dce_i2c_hw->reference_frequency = get_reference_clock(ctx->dc_bios) >> 1;
dce_i2c_hw->reference_frequency = (ctx->dc_bios->fw_info.pll_info.crystal_frequency) >> 1;
dce_i2c_hw->regs = regs;
dce_i2c_hw->shifts = shifts;
dce_i2c_hw->masks = masks;

View File

@ -910,7 +910,6 @@ static bool construct(
{
unsigned int i;
struct dc_context *ctx = dc->ctx;
struct dc_firmware_info info;
struct dc_bios *bp;
ctx->dc_bios->regs = &bios_regs;
@ -921,8 +920,7 @@ static bool construct(
bp = ctx->dc_bios;
if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) &&
info.external_clock_source_frequency_for_dp != 0) {
if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) {
pool->base.dp_clock_source =
dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);

View File

@ -1274,7 +1274,6 @@ static bool construct(
{
unsigned int i;
struct dc_context *ctx = dc->ctx;
struct dc_firmware_info info;
struct dc_bios *bp;
ctx->dc_bios->regs = &bios_regs;
@ -1300,8 +1299,7 @@ static bool construct(
bp = ctx->dc_bios;
if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) &&
info.external_clock_source_frequency_for_dp != 0) {
if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) {
pool->base.dp_clock_source =
dce110_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);

View File

@ -876,7 +876,6 @@ static bool dce80_construct(
{
unsigned int i;
struct dc_context *ctx = dc->ctx;
struct dc_firmware_info info;
struct dc_bios *bp;
ctx->dc_bios->regs = &bios_regs;
@ -902,8 +901,7 @@ static bool dce80_construct(
bp = ctx->dc_bios;
if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) &&
info.external_clock_source_frequency_for_dp != 0) {
if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) {
pool->base.dp_clock_source =
dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
@ -1075,7 +1073,6 @@ static bool dce81_construct(
{
unsigned int i;
struct dc_context *ctx = dc->ctx;
struct dc_firmware_info info;
struct dc_bios *bp;
ctx->dc_bios->regs = &bios_regs;
@ -1101,8 +1098,7 @@ static bool dce81_construct(
bp = ctx->dc_bios;
if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) &&
info.external_clock_source_frequency_for_dp != 0) {
if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) {
pool->base.dp_clock_source =
dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
@ -1274,7 +1270,6 @@ static bool dce83_construct(
{
unsigned int i;
struct dc_context *ctx = dc->ctx;
struct dc_firmware_info info;
struct dc_bios *bp;
ctx->dc_bios->regs = &bios_regs;
@ -1300,8 +1295,7 @@ static bool dce83_construct(
bp = ctx->dc_bios;
if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) &&
info.external_clock_source_frequency_for_dp != 0) {
if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) {
pool->base.dp_clock_source =
dce80_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);

View File

@ -568,7 +568,6 @@ static void dcn20_init_hw(struct dc *dc)
struct dc_bios *dcb = dc->ctx->dc_bios;
struct resource_pool *res_pool = dc->res_pool;
struct dc_state *context = dc->current_state;
struct dc_firmware_info fw_info = { { 0 } };
if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
@ -592,15 +591,15 @@ static void dcn20_init_hw(struct dc *dc)
} else {
if (!dcb->funcs->is_accelerated_mode(dcb)) {
bios_golden_init(dc);
if (dc->ctx->dc_bios->funcs->get_firmware_info(
dc->ctx->dc_bios, &fw_info) == BP_RESULT_OK) {
res_pool->ref_clocks.xtalin_clock_inKhz = fw_info.pll_info.crystal_frequency;
if (dc->ctx->dc_bios->fw_info_valid) {
res_pool->ref_clocks.xtalin_clock_inKhz =
dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;
if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
if (res_pool->dccg && res_pool->hubbub) {
(res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,
fw_info.pll_info.crystal_frequency,
dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,
&res_pool->ref_clocks.dccg_ref_clock_inKhz);
(res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,