On Fri, Oct 11, 2019 at 6:34 AM Kenneth Feng <kenneth.feng@xxxxxxx> wrote: > > Bug fix for pcie paramerers override on swsmu. > Below is a scenario to have this problem. > pptable definition on pcie dpm: > 0 -> pcie gen speed:1, pcie lanes: *16 > 1 -> pcie gen speed:4, pcie lanes: *16 > Then if we have a system only have the capbility: > pcie gen speed: 3, pcie lanes: *8, > we will override dpm 1 to pcie gen speed 3, pcie lanes *8. > But the code skips the dpm 0 configuration. > So the real pcie dpm parameters are: > 0 -> pcie gen speed:1, pcie lanes: *16 > 1 -> pcie gen speed:3, pcie lanes: *8 > Then the wrong pcie lanes will be toggled. > > Signed-off-by: Kenneth Feng <kenneth.feng@xxxxxxx> Reviewed-by: Alex Deucher <alexander.deucher@xxxxxxx> > --- > drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 44 -------------------------- > drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 8 +++++ > drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 23 ++++++++++++++ > drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 44 ++++++++++++++++++++++++++ > drivers/gpu/drm/amd/powerplay/vega20_ppt.c | 25 ++++++++++++++- > 5 files changed, 99 insertions(+), 45 deletions(-) > > diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c > index c9266ea..de54da2 100644 > --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c > +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c > @@ -945,50 +945,6 @@ static int smu_fini_fb_allocations(struct smu_context *smu) > return 0; > } > > -static int smu_override_pcie_parameters(struct smu_context *smu) > -{ > - struct amdgpu_device *adev = smu->adev; > - uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg; > - int ret; > - > - if (adev->flags & AMD_IS_APU) > - return 0; > - > - if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) > - pcie_gen = 3; > - else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) > - pcie_gen = 2; > - else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) > - pcie_gen = 1; > - else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1) > - pcie_gen = 0; > - > - /* Bit 31:16: LCLK DPM level. 0 is DPM0, and 1 is DPM1 > - * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4 > - * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 > - */ > - if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) > - pcie_width = 6; > - else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12) > - pcie_width = 5; > - else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8) > - pcie_width = 4; > - else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4) > - pcie_width = 3; > - else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2) > - pcie_width = 2; > - else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1) > - pcie_width = 1; > - > - smu_pcie_arg = (1 << 16) | (pcie_gen << 8) | pcie_width; > - ret = smu_send_smc_msg_with_param(smu, > - SMU_MSG_OverridePcieParameters, > - smu_pcie_arg); > - if (ret) > - pr_err("[%s] Attempt to override pcie params failed!\n", __func__); > - return ret; > -} > - > static int smu_smc_table_hw_init(struct smu_context *smu, > bool initialize) > { > diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h > index ccf711c..809de0d 100644 > --- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h > +++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h > @@ -468,6 +468,7 @@ struct pptable_funcs { > int (*get_power_limit)(struct smu_context *smu, uint32_t *limit, bool asic_default); > int (*get_dpm_clk_limited)(struct smu_context *smu, enum smu_clk_type clk_type, > uint32_t dpm_level, uint32_t *freq); > + int (*update_pcie_parameters)(struct smu_context *smu, uint32_t pcie_gen_cap, uint32_t pcie_width_cap); > }; > > struct smu_funcs > @@ -550,6 +551,7 @@ struct smu_funcs > int (*mode2_reset)(struct smu_context *smu); > int (*get_dpm_ultimate_freq)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t *min, uint32_t *max); > int (*set_soft_freq_limited_range)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t min, uint32_t max); > + int (*override_pcie_parameters)(struct smu_context *smu); > }; > > #define smu_init_microcode(smu) \ > @@ -782,6 +784,12 @@ struct smu_funcs > #define smu_set_soft_freq_limited_range(smu, clk_type, min, max) \ > ((smu)->funcs->set_soft_freq_limited_range ? (smu)->funcs->set_soft_freq_limited_range((smu), (clk_type), (min), (max)) : -EINVAL) > > +#define smu_override_pcie_parameters(smu) \ > + ((smu)->funcs->override_pcie_parameters ? (smu)->funcs->override_pcie_parameters((smu)) : 0) > + > +#define smu_update_pcie_parameters(smu, pcie_gen_cap, pcie_width_cap) \ > + ((smu)->ppt_funcs->update_pcie_parameters ? (smu)->ppt_funcs->update_pcie_parameters((smu), (pcie_gen_cap), (pcie_width_cap)) : 0) > + > extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table, > uint16_t *size, uint8_t *frev, uint8_t *crev, > uint8_t **addr); > diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c > index a583cf8..a2f33cf 100644 > --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c > +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c > @@ -1592,6 +1592,28 @@ static int navi10_get_power_limit(struct smu_context *smu, > return 0; > } > > +static int navi10_update_pcie_parameters(struct smu_context *smu, > + uint32_t pcie_gen_cap, > + uint32_t pcie_width_cap) > +{ > + PPTable_t *pptable = smu->smu_table.driver_pptable; > + int ret, i; > + uint32_t smu_pcie_arg; > + > + for (i = 0; i < NUM_LINK_LEVELS; i++) { > + smu_pcie_arg = (i << 16) | > + ((pptable->PcieGenSpeed[i] <= pcie_gen_cap) ? (pptable->PcieGenSpeed[i] << 8) : > + (pcie_gen_cap << 8)) | ((pptable->PcieLaneCount[i] <= pcie_width_cap) ? > + pptable->PcieLaneCount[i] : pcie_width_cap); > + ret = smu_send_smc_msg_with_param(smu, > + SMU_MSG_OverridePcieParameters, > + smu_pcie_arg); > + } > + > + return ret; > +} > + > + > static const struct pptable_funcs navi10_ppt_funcs = { > .tables_init = navi10_tables_init, > .alloc_dpm_context = navi10_allocate_dpm_context, > @@ -1630,6 +1652,7 @@ static const struct pptable_funcs navi10_ppt_funcs = { > .get_thermal_temperature_range = navi10_get_thermal_temperature_range, > .display_disable_memory_clock_switch = navi10_display_disable_memory_clock_switch, > .get_power_limit = navi10_get_power_limit, > + .update_pcie_parameters = navi10_update_pcie_parameters, > }; > > void navi10_set_ppt_funcs(struct smu_context *smu) > diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c > index c9e90d5..a812ae5 100644 > --- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c > +++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c > @@ -35,6 +35,7 @@ > #include "vega20_ppt.h" > #include "arcturus_ppt.h" > #include "navi10_ppt.h" > +#include "amd_pcie.h" > > #include "asic_reg/thm/thm_11_0_2_offset.h" > #include "asic_reg/thm/thm_11_0_2_sh_mask.h" > @@ -1792,6 +1793,48 @@ static int smu_v11_0_set_soft_freq_limited_range(struct smu_context *smu, enum s > return ret; > } > > +static int smu_v11_0_override_pcie_parameters(struct smu_context *smu) > +{ > + struct amdgpu_device *adev = smu->adev; > + uint32_t pcie_gen = 0, pcie_width = 0; > + int ret; > + > + if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) > + pcie_gen = 3; > + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) > + pcie_gen = 2; > + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) > + pcie_gen = 1; > + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1) > + pcie_gen = 0; > + > + /* Bit 31:16: LCLK DPM level. 0 is DPM0, and 1 is DPM1 > + * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4 > + * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 > + */ > + if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) > + pcie_width = 6; > + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12) > + pcie_width = 5; > + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8) > + pcie_width = 4; > + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4) > + pcie_width = 3; > + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2) > + pcie_width = 2; > + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1) > + pcie_width = 1; > + > + ret = smu_update_pcie_parameters(smu, pcie_gen, pcie_width); > + > + if (ret) > + pr_err("[%s] Attempt to override pcie params failed!\n", __func__); > + > + return ret; > + > +} > + > + > static const struct smu_funcs smu_v11_0_funcs = { > .init_microcode = smu_v11_0_init_microcode, > .load_microcode = smu_v11_0_load_microcode, > @@ -1844,6 +1887,7 @@ static const struct smu_funcs smu_v11_0_funcs = { > .baco_reset = smu_v11_0_baco_reset, > .get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq, > .set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range, > + .override_pcie_parameters = smu_v11_0_override_pcie_parameters, > }; > > void smu_v11_0_set_smu_funcs(struct smu_context *smu) > diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c > index f655ebd..adca84a 100644 > --- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c > +++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c > @@ -3135,6 +3135,28 @@ static int vega20_get_thermal_temperature_range(struct smu_context *smu, > return 0; > } > > +static int vega20_update_pcie_parameters(struct smu_context *smu, > + uint32_t pcie_gen_cap, > + uint32_t pcie_width_cap) > +{ > + PPTable_t *pptable = smu->smu_table.driver_pptable; > + int ret, i; > + uint32_t smu_pcie_arg; > + > + for (i = 0; i < NUM_LINK_LEVELS; i++) { > + smu_pcie_arg = (i << 16) | > + ((pptable->PcieGenSpeed[i] <= pcie_gen_cap) ? (pptable->PcieGenSpeed[i] << 8) : > + (pcie_gen_cap << 8)) | ((pptable->PcieLaneCount[i] <= pcie_width_cap) ? > + pptable->PcieLaneCount[i] : pcie_width_cap); > + ret = smu_send_smc_msg_with_param(smu, > + SMU_MSG_OverridePcieParameters, > + smu_pcie_arg); > + } > + > + return ret; > +} > + > + > static const struct pptable_funcs vega20_ppt_funcs = { > .tables_init = vega20_tables_init, > .alloc_dpm_context = vega20_allocate_dpm_context, > @@ -3177,7 +3199,8 @@ static const struct pptable_funcs vega20_ppt_funcs = { > .get_fan_speed_percent = vega20_get_fan_speed_percent, > .get_fan_speed_rpm = vega20_get_fan_speed_rpm, > .set_watermarks_table = vega20_set_watermarks_table, > - .get_thermal_temperature_range = vega20_get_thermal_temperature_range > + .get_thermal_temperature_range = vega20_get_thermal_temperature_range, > + .update_pcie_parameters = vega20_update_pcie_parameters > }; > > void vega20_set_ppt_funcs(struct smu_context *smu) > -- > 2.7.4 > > _______________________________________________ > amd-gfx mailing list > amd-gfx@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/amd-gfx _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx