OSDN Git Service

drm/amd/display: make firmware info only load once during dc_bios create
authorDmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Fri, 12 Jul 2019 19:06:06 +0000 (15:06 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 15 Aug 2019 15:53:36 +0000 (10:53 -0500)
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>
12 files changed:
drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
drivers/gpu/drm/amd/display/dc/dc_bios_types.h
drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c
drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c

index 461eef1..221e0f5 100644 (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;
 }
index 6aa2e56..dff65c0 100644 (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;
 }
index 814450f..c5c8c49 100644 (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)
index caf8a4a..39c1dea 100644 (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;
        }
index c227b86..5956e70 100644 (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
index 78c3b30..b1dd0d6 100644 (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 */
index 5fae77e..1bda7cb 100644 (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;
 }
index a9061aa..420b18f 100644 (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;
index 8111628..afc6105 100644 (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);
 
index 765e264..c66fe17 100644 (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);
 
index 2a1ce9e..4625df9 100644 (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);
 
index 27d1434..fb7cde3 100644 (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,