Commit 9adc8050 authored by Dmytro Laktyushkin's avatar Dmytro Laktyushkin Committed by Alex Deucher

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: default avatarDmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Reviewed-by: default avatarChris Park <Chris.Park@amd.com>
Acked-by: default avatarLeo Li <sunpeng.li@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 0b226322
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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)
......
......@@ -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;
}
......
......@@ -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
......
......@@ -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 */
......@@ -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;
}
......
......@@ -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;
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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,
......
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