.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,
        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;
 }
 
 
        .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,
        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;
 }
 
 {
        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;
        }
 
                /*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)
 
 {
        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;
 
        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;
        }
 
                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
 
                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,
        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 */
 
                        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;
        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;
 
        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;
                        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;
        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;
        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;
 }
 
                        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)
 {
 {
        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;
 
 {
        unsigned int i;
        struct dc_context *ctx = dc->ctx;
-       struct dc_firmware_info info;
        struct dc_bios *bp;
 
        ctx->dc_bios->regs = &bios_regs;
 
        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);
 
 
 {
        unsigned int i;
        struct dc_context *ctx = dc->ctx;
-       struct dc_firmware_info info;
        struct dc_bios *bp;
 
        ctx->dc_bios->regs = &bios_regs;
 
        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);
 
 
 {
        unsigned int i;
        struct dc_context *ctx = dc->ctx;
-       struct dc_firmware_info info;
        struct dc_bios *bp;
 
        ctx->dc_bios->regs = &bios_regs;
 
        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);
 
 {
        unsigned int i;
        struct dc_context *ctx = dc->ctx;
-       struct dc_firmware_info info;
        struct dc_bios *bp;
 
        ctx->dc_bios->regs = &bios_regs;
 
        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);
 
 {
        unsigned int i;
        struct dc_context *ctx = dc->ctx;
-       struct dc_firmware_info info;
        struct dc_bios *bp;
 
        ctx->dc_bios->regs = &bios_regs;
 
        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);
 
 
        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);
        } 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,