On Tue, Jun 19, 2018 at 3:38 AM, Evan Quan <evan.q...@amd.com> wrote: > Initialize the soft/hard min/max level correctly and > handle the dpm disabled situation. > > Change-Id: I9a1d303ee54ac4c9687f72c86097b008ae398c05 > Signed-off-by: Evan Quan <evan.q...@amd.com>
Acked-by: Alex Deucher <alexander.deuc...@amd.com> > --- > drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 334 > ++++++++------------- > 1 file changed, 132 insertions(+), 202 deletions(-) > > diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c > b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c > index e81661cc..bc976e1 100644 > --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c > +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c > @@ -453,37 +453,30 @@ static int vega12_setup_asic_task(struct pp_hwmgr > *hwmgr) > */ > static void vega12_init_dpm_state(struct vega12_dpm_state *dpm_state) > { > - dpm_state->soft_min_level = 0xff; > - dpm_state->soft_max_level = 0xff; > - dpm_state->hard_min_level = 0xff; > - dpm_state->hard_max_level = 0xff; > + dpm_state->soft_min_level = 0x0; > + dpm_state->soft_max_level = 0xffff; > + dpm_state->hard_min_level = 0x0; > + dpm_state->hard_max_level = 0xffff; > } > > -static int vega12_get_number_dpm_level(struct pp_hwmgr *hwmgr, > - PPCLK_e clkID, uint32_t *num_dpm_level) > +static int vega12_get_number_of_dpm_level(struct pp_hwmgr *hwmgr, > + PPCLK_e clk_id, uint32_t *num_of_levels) > { > - int result; > - /* > - * SMU expects the Clock ID to be in the top 16 bits. > - * Lower 16 bits specify the level however 0xFF is a > - * special argument the returns the total number of levels > - */ > - PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr, > - PPSMC_MSG_GetDpmFreqByIndex, (clkID << 16 | 0xFF)) == 0, > - "[GetNumberDpmLevel] Failed to get DPM levels from SMU for > CLKID!", > - return -EINVAL); > - > - result = vega12_read_arg_from_smc(hwmgr, num_dpm_level); > + int ret = 0; > > - PP_ASSERT_WITH_CODE(*num_dpm_level < MAX_REGULAR_DPM_NUMBER, > - "[GetNumberDPMLevel] Number of DPM levels is greater than > limit", > - return -EINVAL); > + ret = smum_send_msg_to_smc_with_parameter(hwmgr, > + PPSMC_MSG_GetDpmFreqByIndex, > + (clk_id << 16 | 0xFF)); > + PP_ASSERT_WITH_CODE(!ret, > + "[GetNumOfDpmLevel] failed to get dpm levels!", > + return ret); > > - PP_ASSERT_WITH_CODE(*num_dpm_level != 0, > - "[GetNumberDPMLevel] Number of CLK Levels is zero!", > - return -EINVAL); > + vega12_read_arg_from_smc(hwmgr, num_of_levels); > + PP_ASSERT_WITH_CODE(*num_of_levels > 0, > + "[GetNumOfDpmLevel] number of clk levels is invalid!", > + return -EINVAL); > > - return result; > + return ret; > } > > static int vega12_get_dpm_frequency_by_index(struct pp_hwmgr *hwmgr, > @@ -509,6 +502,31 @@ static int vega12_get_dpm_frequency_by_index(struct > pp_hwmgr *hwmgr, > return result; > } > > +static int vega12_setup_single_dpm_table(struct pp_hwmgr *hwmgr, > + struct vega12_single_dpm_table *dpm_table, PPCLK_e clk_id) > +{ > + int ret = 0; > + uint32_t i, num_of_levels, clk; > + > + ret = vega12_get_number_of_dpm_level(hwmgr, clk_id, &num_of_levels); > + PP_ASSERT_WITH_CODE(!ret, > + "[SetupSingleDpmTable] failed to get clk levels!", > + return ret); > + > + dpm_table->count = num_of_levels; > + > + for (i = 0; i < num_of_levels; i++) { > + ret = vega12_get_dpm_frequency_by_index(hwmgr, clk_id, i, > &clk); > + PP_ASSERT_WITH_CODE(!ret, > + "[SetupSingleDpmTable] failed to get clk of specific > level!", > + return ret); > + dpm_table->dpm_levels[i].value = clk; > + dpm_table->dpm_levels[i].enabled = true; > + } > + > + return ret; > +} > + > /* > * This function is to initialize all DPM state tables > * for SMU based on the dependency table. > @@ -519,224 +537,136 @@ static int vega12_get_dpm_frequency_by_index(struct > pp_hwmgr *hwmgr, > */ > static int vega12_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) > { > - uint32_t num_levels, i, clock; > > struct vega12_hwmgr *data = > (struct vega12_hwmgr *)(hwmgr->backend); > - > struct vega12_single_dpm_table *dpm_table; > + int ret = 0; > > memset(&data->dpm_table, 0, sizeof(data->dpm_table)); > > - /* Initialize Sclk DPM and SOC DPM table based on allow Sclk values */ > + /* socclk */ > dpm_table = &(data->dpm_table.soc_table); > - > - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_SOCCLK, > - &num_levels) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU > for SOCCLK!", > - return -EINVAL); > - > - dpm_table->count = num_levels; > - > - for (i = 0; i < num_levels; i++) { > - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, > - PPCLK_SOCCLK, i, &clock) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels > from SMU for SOCCLK!", > - return -EINVAL); > - > - dpm_table->dpm_levels[i].value = clock; > - dpm_table->dpm_levels[i].enabled = true; > + if (data->smu_features[GNLD_DPM_SOCCLK].enabled) { > + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, > PPCLK_SOCCLK); > + PP_ASSERT_WITH_CODE(!ret, > + "[SetupDefaultDpmTable] failed to get socclk > dpm levels!", > + return ret); > + } else { > + dpm_table->count = 1; > + dpm_table->dpm_levels[0].value = > data->vbios_boot_state.soc_clock / 100; > } > - > vega12_init_dpm_state(&(dpm_table->dpm_state)); > > + /* gfxclk */ > dpm_table = &(data->dpm_table.gfx_table); > - > - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_GFXCLK, > - &num_levels) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU > for GFXCLK!", > - return -EINVAL); > - > - dpm_table->count = num_levels; > - for (i = 0; i < num_levels; i++) { > - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, > - PPCLK_GFXCLK, i, &clock) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels > from SMU for GFXCLK!", > - return -EINVAL); > - > - dpm_table->dpm_levels[i].value = clock; > - dpm_table->dpm_levels[i].enabled = true; > + if (data->smu_features[GNLD_DPM_GFXCLK].enabled) { > + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, > PPCLK_GFXCLK); > + PP_ASSERT_WITH_CODE(!ret, > + "[SetupDefaultDpmTable] failed to get gfxclk > dpm levels!", > + return ret); > + } else { > + dpm_table->count = 1; > + dpm_table->dpm_levels[0].value = > data->vbios_boot_state.gfx_clock / 100; > } > - > vega12_init_dpm_state(&(dpm_table->dpm_state)); > - /* Initialize Mclk DPM table based on allow Mclk values */ > - dpm_table = &(data->dpm_table.mem_table); > > - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_UCLK, > - &num_levels) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU > for UCLK!", > - return -EINVAL); > - > - dpm_table->count = num_levels; > - > - for (i = 0; i < num_levels; i++) { > - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, > - PPCLK_UCLK, i, &clock) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels > from SMU for UCLK!", > - return -EINVAL); > - > - dpm_table->dpm_levels[i].value = clock; > - dpm_table->dpm_levels[i].enabled = true; > + /* memclk */ > + dpm_table = &(data->dpm_table.mem_table); > + if (data->smu_features[GNLD_DPM_UCLK].enabled) { > + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, > PPCLK_UCLK); > + PP_ASSERT_WITH_CODE(!ret, > + "[SetupDefaultDpmTable] failed to get memclk > dpm levels!", > + return ret); > + } else { > + dpm_table->count = 1; > + dpm_table->dpm_levels[0].value = > data->vbios_boot_state.mem_clock / 100; > } > - > vega12_init_dpm_state(&(dpm_table->dpm_state)); > > + /* eclk */ > dpm_table = &(data->dpm_table.eclk_table); > - > - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_ECLK, > - &num_levels) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU > for ECLK!", > - return -EINVAL); > - > - dpm_table->count = num_levels; > - > - for (i = 0; i < num_levels; i++) { > - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, > - PPCLK_ECLK, i, &clock) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU > for ECLK!", > - return -EINVAL); > - > - dpm_table->dpm_levels[i].value = clock; > - dpm_table->dpm_levels[i].enabled = true; > + if (data->smu_features[GNLD_DPM_VCE].enabled) { > + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, > PPCLK_ECLK); > + PP_ASSERT_WITH_CODE(!ret, > + "[SetupDefaultDpmTable] failed to get eclk > dpm levels!", > + return ret); > + } else { > + dpm_table->count = 1; > + dpm_table->dpm_levels[0].value = > data->vbios_boot_state.eclock / 100; > } > - > vega12_init_dpm_state(&(dpm_table->dpm_state)); > > + /* vclk */ > dpm_table = &(data->dpm_table.vclk_table); > - > - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_VCLK, > - &num_levels) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU > for VCLK!", > - return -EINVAL); > - > - dpm_table->count = num_levels; > - > - for (i = 0; i < num_levels; i++) { > - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, > - PPCLK_VCLK, i, &clock) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels > from SMU for VCLK!", > - return -EINVAL); > - > - dpm_table->dpm_levels[i].value = clock; > - dpm_table->dpm_levels[i].enabled = true; > + if (data->smu_features[GNLD_DPM_UVD].enabled) { > + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, > PPCLK_VCLK); > + PP_ASSERT_WITH_CODE(!ret, > + "[SetupDefaultDpmTable] failed to get vclk > dpm levels!", > + return ret); > + } else { > + dpm_table->count = 1; > + dpm_table->dpm_levels[0].value = > data->vbios_boot_state.vclock / 100; > } > - > vega12_init_dpm_state(&(dpm_table->dpm_state)); > > + /* dclk */ > dpm_table = &(data->dpm_table.dclk_table); > - > - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_DCLK, > - &num_levels) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU > for DCLK!", > - return -EINVAL); > - > - dpm_table->count = num_levels; > - > - for (i = 0; i < num_levels; i++) { > - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, > - PPCLK_DCLK, i, &clock) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU > for DCLK!", > - return -EINVAL); > - > - dpm_table->dpm_levels[i].value = clock; > - dpm_table->dpm_levels[i].enabled = true; > + if (data->smu_features[GNLD_DPM_UVD].enabled) { > + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, > PPCLK_DCLK); > + PP_ASSERT_WITH_CODE(!ret, > + "[SetupDefaultDpmTable] failed to get dclk > dpm levels!", > + return ret); > + } else { > + dpm_table->count = 1; > + dpm_table->dpm_levels[0].value = > data->vbios_boot_state.dclock / 100; > } > - > vega12_init_dpm_state(&(dpm_table->dpm_state)); > > - /* Assume there is no headless Vega12 for now */ > + /* dcefclk */ > dpm_table = &(data->dpm_table.dcef_table); > - > - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, > - PPCLK_DCEFCLK, &num_levels) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU > for DCEFCLK!", > - return -EINVAL); > - > - dpm_table->count = num_levels; > - > - for (i = 0; i < num_levels; i++) { > - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, > - PPCLK_DCEFCLK, i, &clock) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels > from SMU for DCEFCLK!", > - return -EINVAL); > - > - dpm_table->dpm_levels[i].value = clock; > - dpm_table->dpm_levels[i].enabled = true; > + if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) { > + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, > PPCLK_DCEFCLK); > + PP_ASSERT_WITH_CODE(!ret, > + "[SetupDefaultDpmTable] failed to get dcefclk > dpm levels!", > + return ret); > + } else { > + dpm_table->count = 1; > + dpm_table->dpm_levels[0].value = > data->vbios_boot_state.dcef_clock / 100; > } > - > vega12_init_dpm_state(&(dpm_table->dpm_state)); > > + /* pixclk */ > dpm_table = &(data->dpm_table.pixel_table); > - > - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, > - PPCLK_PIXCLK, &num_levels) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU > for PIXCLK!", > - return -EINVAL); > - > - dpm_table->count = num_levels; > - > - for (i = 0; i < num_levels; i++) { > - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, > - PPCLK_PIXCLK, i, &clock) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels > from SMU for PIXCLK!", > - return -EINVAL); > - > - dpm_table->dpm_levels[i].value = clock; > - dpm_table->dpm_levels[i].enabled = true; > - } > - > + if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) { > + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, > PPCLK_PIXCLK); > + PP_ASSERT_WITH_CODE(!ret, > + "[SetupDefaultDpmTable] failed to get pixclk > dpm levels!", > + return ret); > + } else > + dpm_table->count = 0; > vega12_init_dpm_state(&(dpm_table->dpm_state)); > > + /* dispclk */ > dpm_table = &(data->dpm_table.display_table); > - > - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, > - PPCLK_DISPCLK, &num_levels) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU > for DISPCLK!", > - return -EINVAL); > - > - dpm_table->count = num_levels; > - > - for (i = 0; i < num_levels; i++) { > - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, > - PPCLK_DISPCLK, i, &clock) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels > from SMU for DISPCLK!", > - return -EINVAL); > - > - dpm_table->dpm_levels[i].value = clock; > - dpm_table->dpm_levels[i].enabled = true; > - } > - > + if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) { > + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, > PPCLK_DISPCLK); > + PP_ASSERT_WITH_CODE(!ret, > + "[SetupDefaultDpmTable] failed to get dispclk > dpm levels!", > + return ret); > + } else > + dpm_table->count = 0; > vega12_init_dpm_state(&(dpm_table->dpm_state)); > > + /* phyclk */ > dpm_table = &(data->dpm_table.phy_table); > - > - PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, > - PPCLK_PHYCLK, &num_levels) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels from SMU > for PHYCLK!", > - return -EINVAL); > - > - dpm_table->count = num_levels; > - > - for (i = 0; i < num_levels; i++) { > - PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr, > - PPCLK_PHYCLK, i, &clock) == 0, > - "[SetupDefaultDPMTables] Failed to get DPM levels > from SMU for PHYCLK!", > - return -EINVAL); > - > - dpm_table->dpm_levels[i].value = clock; > - dpm_table->dpm_levels[i].enabled = true; > - } > - > + if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) { > + ret = vega12_setup_single_dpm_table(hwmgr, dpm_table, > PPCLK_PHYCLK); > + PP_ASSERT_WITH_CODE(!ret, > + "[SetupDefaultDpmTable] failed to get phyclk > dpm levels!", > + return ret); > + } else > + dpm_table->count = 0; > vega12_init_dpm_state(&(dpm_table->dpm_state)); > > /* save a copy of the default DPM table */ > -- > 2.7.4 > > _______________________________________________ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx _______________________________________________ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx