<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Reviewed-by: Kevin Wang <kevin1.wang@amd.com></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Best Regards,<br>
Kevin</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> amd-gfx <amd-gfx-bounces@lists.freedesktop.org> on behalf of Kenneth Feng <kenneth.feng@amd.com><br>
<b>Sent:</b> Friday, October 11, 2019 6:33 PM<br>
<b>To:</b> amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org><br>
<b>Cc:</b> Feng, Kenneth <Kenneth.Feng@amd.com><br>
<b>Subject:</b> [PATCH v2] drm/amd/powerplay: bug fix for pcie parameters override</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt">
<div class="PlainText">Bug fix for pcie paramerers override on swsmu.<br>
Below is a scenario to have this problem.<br>
pptable definition on pcie dpm:<br>
0 -> pcie gen speed:1, pcie lanes: *16<br>
1 -> pcie gen speed:4, pcie lanes: *16<br>
Then if we have a system only have the capbility:<br>
pcie gen speed: 3, pcie lanes: *8,<br>
we will override dpm 1 to pcie gen speed 3, pcie lanes *8.<br>
But the code skips the dpm 0 configuration.<br>
So the real pcie dpm parameters are:<br>
0 -> pcie gen speed:1, pcie lanes: *16<br>
1 -> pcie gen speed:3, pcie lanes: *8<br>
Then the wrong pcie lanes will be toggled.<br>
<br>
Signed-off-by: Kenneth Feng <kenneth.feng@amd.com><br>
---<br>
 drivers/gpu/drm/amd/powerplay/amdgpu_smu.c     | 44 --------------------------<br>
 drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h |  8 +++++<br>
 drivers/gpu/drm/amd/powerplay/navi10_ppt.c     | 23 ++++++++++++++<br>
 drivers/gpu/drm/amd/powerplay/smu_v11_0.c      | 44 ++++++++++++++++++++++++++<br>
 drivers/gpu/drm/amd/powerplay/vega20_ppt.c     | 25 ++++++++++++++-<br>
 5 files changed, 99 insertions(+), 45 deletions(-)<br>
<br>
diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c<br>
index c9266ea..de54da2 100644<br>
--- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c<br>
+++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c<br>
@@ -945,50 +945,6 @@ static int smu_fini_fb_allocations(struct smu_context *smu)<br>
         return 0;<br>
 }<br>
 <br>
-static int smu_override_pcie_parameters(struct smu_context *smu)<br>
-{<br>
-       struct amdgpu_device *adev = smu->adev;<br>
-       uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg;<br>
-       int ret;<br>
-<br>
-       if (adev->flags & AMD_IS_APU)<br>
-               return 0;<br>
-<br>
-       if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4)<br>
-               pcie_gen = 3;<br>
-       else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)<br>
-               pcie_gen = 2;<br>
-       else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2)<br>
-               pcie_gen = 1;<br>
-       else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1)<br>
-               pcie_gen = 0;<br>
-<br>
-       /* Bit 31:16: LCLK DPM level. 0 is DPM0, and 1 is DPM1<br>
-        * Bit 15:8:  PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4<br>
-        * Bit 7:0:   PCIE lane width, 1 to 7 corresponds is x1 to x32<br>
-        */<br>
-       if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16)<br>
-               pcie_width = 6;<br>
-       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12)<br>
-               pcie_width = 5;<br>
-       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8)<br>
-               pcie_width = 4;<br>
-       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4)<br>
-               pcie_width = 3;<br>
-       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2)<br>
-               pcie_width = 2;<br>
-       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1)<br>
-               pcie_width = 1;<br>
-<br>
-       smu_pcie_arg = (1 << 16) | (pcie_gen << 8) | pcie_width;<br>
-       ret = smu_send_smc_msg_with_param(smu,<br>
-                                         SMU_MSG_OverridePcieParameters,<br>
-                                         smu_pcie_arg);<br>
-       if (ret)<br>
-               pr_err("[%s] Attempt to override pcie params failed!\n", __func__);<br>
-       return ret;<br>
-}<br>
-<br>
 static int smu_smc_table_hw_init(struct smu_context *smu,<br>
                                  bool initialize)<br>
 {<br>
diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h<br>
index ccf711c..809de0d 100644<br>
--- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h<br>
+++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h<br>
@@ -468,6 +468,7 @@ struct pptable_funcs {<br>
         int (*get_power_limit)(struct smu_context *smu, uint32_t *limit, bool asic_default);<br>
         int (*get_dpm_clk_limited)(struct smu_context *smu, enum smu_clk_type clk_type,<br>
                                    uint32_t dpm_level, uint32_t *freq);<br>
+       int (*update_pcie_parameters)(struct smu_context *smu, uint32_t pcie_gen_cap, uint32_t pcie_width_cap);<br>
 };<br>
 <br>
 struct smu_funcs<br>
@@ -550,6 +551,7 @@ struct smu_funcs<br>
         int (*mode2_reset)(struct smu_context *smu);<br>
         int (*get_dpm_ultimate_freq)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t *min, uint32_t *max);<br>
         int (*set_soft_freq_limited_range)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t min, uint32_t max);<br>
+       int (*override_pcie_parameters)(struct smu_context *smu);<br>
 };<br>
 <br>
 #define smu_init_microcode(smu) \<br>
@@ -782,6 +784,12 @@ struct smu_funcs<br>
 #define smu_set_soft_freq_limited_range(smu, clk_type, min, max) \<br>
                 ((smu)->funcs->set_soft_freq_limited_range ? (smu)->funcs->set_soft_freq_limited_range((smu), (clk_type), (min), (max)) : -EINVAL)<br>
 <br>
+#define smu_override_pcie_parameters(smu) \<br>
+               ((smu)->funcs->override_pcie_parameters ? (smu)->funcs->override_pcie_parameters((smu)) : 0)<br>
+<br>
+#define smu_update_pcie_parameters(smu, pcie_gen_cap, pcie_width_cap) \<br>
+               ((smu)->ppt_funcs->update_pcie_parameters ? (smu)->ppt_funcs->update_pcie_parameters((smu), (pcie_gen_cap), (pcie_width_cap)) : 0)<br>
+<br>
 extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table,<br>
                                    uint16_t *size, uint8_t *frev, uint8_t *crev,<br>
                                    uint8_t **addr);<br>
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c<br>
index a583cf8..a2f33cf 100644<br>
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c<br>
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c<br>
@@ -1592,6 +1592,28 @@ static int navi10_get_power_limit(struct smu_context *smu,<br>
         return 0;<br>
 }<br>
 <br>
+static int navi10_update_pcie_parameters(struct smu_context *smu,<br>
+                                    uint32_t pcie_gen_cap,<br>
+                                    uint32_t pcie_width_cap)<br>
+{<br>
+       PPTable_t *pptable = smu->smu_table.driver_pptable;<br>
+       int ret, i;<br>
+       uint32_t smu_pcie_arg;<br>
+<br>
+       for (i = 0; i < NUM_LINK_LEVELS; i++) {<br>
+               smu_pcie_arg = (i << 16) |<br>
+                       ((pptable->PcieGenSpeed[i] <= pcie_gen_cap) ? (pptable->PcieGenSpeed[i] << 8) :<br>
+                               (pcie_gen_cap << 8)) | ((pptable->PcieLaneCount[i] <= pcie_width_cap) ?<br>
+                                       pptable->PcieLaneCount[i] : pcie_width_cap);<br>
+               ret = smu_send_smc_msg_with_param(smu,<br>
+                                         SMU_MSG_OverridePcieParameters,<br>
+                                         smu_pcie_arg);<br>
+       }<br>
+<br>
+       return ret;<br>
+}<br>
+<br>
+<br>
 static const struct pptable_funcs navi10_ppt_funcs = {<br>
         .tables_init = navi10_tables_init,<br>
         .alloc_dpm_context = navi10_allocate_dpm_context,<br>
@@ -1630,6 +1652,7 @@ static const struct pptable_funcs navi10_ppt_funcs = {<br>
         .get_thermal_temperature_range = navi10_get_thermal_temperature_range,<br>
         .display_disable_memory_clock_switch = navi10_display_disable_memory_clock_switch,<br>
         .get_power_limit = navi10_get_power_limit,<br>
+       .update_pcie_parameters = navi10_update_pcie_parameters,<br>
 };<br>
 <br>
 void navi10_set_ppt_funcs(struct smu_context *smu)<br>
diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c<br>
index c9e90d5..a812ae5 100644<br>
--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c<br>
+++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c<br>
@@ -35,6 +35,7 @@<br>
 #include "vega20_ppt.h"<br>
 #include "arcturus_ppt.h"<br>
 #include "navi10_ppt.h"<br>
+#include "amd_pcie.h"<br>
 <br>
 #include "asic_reg/thm/thm_11_0_2_offset.h"<br>
 #include "asic_reg/thm/thm_11_0_2_sh_mask.h"<br>
@@ -1792,6 +1793,48 @@ static int smu_v11_0_set_soft_freq_limited_range(struct smu_context *smu, enum s<br>
         return ret;<br>
 }<br>
 <br>
+static int smu_v11_0_override_pcie_parameters(struct smu_context *smu)<br>
+{<br>
+       struct amdgpu_device *adev = smu->adev;<br>
+       uint32_t pcie_gen = 0, pcie_width = 0;<br>
+       int ret;<br>
+<br>
+       if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4)<br>
+               pcie_gen = 3;<br>
+       else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)<br>
+               pcie_gen = 2;<br>
+       else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2)<br>
+               pcie_gen = 1;<br>
+       else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1)<br>
+               pcie_gen = 0;<br>
+<br>
+       /* Bit 31:16: LCLK DPM level. 0 is DPM0, and 1 is DPM1<br>
+        * Bit 15:8:  PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4<br>
+        * Bit 7:0:   PCIE lane width, 1 to 7 corresponds is x1 to x32<br>
+        */<br>
+       if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16)<br>
+               pcie_width = 6;<br>
+       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12)<br>
+               pcie_width = 5;<br>
+       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8)<br>
+               pcie_width = 4;<br>
+       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4)<br>
+               pcie_width = 3;<br>
+       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2)<br>
+               pcie_width = 2;<br>
+       else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1)<br>
+               pcie_width = 1;<br>
+<br>
+       ret = smu_update_pcie_parameters(smu, pcie_gen, pcie_width);<br>
+<br>
+       if (ret)<br>
+               pr_err("[%s] Attempt to override pcie params failed!\n", __func__);<br>
+<br>
+       return ret;<br>
+<br>
+}<br>
+<br>
+<br>
 static const struct smu_funcs smu_v11_0_funcs = {<br>
         .init_microcode = smu_v11_0_init_microcode,<br>
         .load_microcode = smu_v11_0_load_microcode,<br>
@@ -1844,6 +1887,7 @@ static const struct smu_funcs smu_v11_0_funcs = {<br>
         .baco_reset = smu_v11_0_baco_reset,<br>
         .get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq,<br>
         .set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range,<br>
+       .override_pcie_parameters = smu_v11_0_override_pcie_parameters,<br>
 };<br>
 <br>
 void smu_v11_0_set_smu_funcs(struct smu_context *smu)<br>
diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c<br>
index f655ebd..adca84a 100644<br>
--- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c<br>
+++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c<br>
@@ -3135,6 +3135,28 @@ static int vega20_get_thermal_temperature_range(struct smu_context *smu,<br>
         return 0;<br>
 }<br>
 <br>
+static int vega20_update_pcie_parameters(struct smu_context *smu,<br>
+                                    uint32_t pcie_gen_cap,<br>
+                                    uint32_t pcie_width_cap)<br>
+{<br>
+       PPTable_t *pptable = smu->smu_table.driver_pptable;<br>
+       int ret, i;<br>
+       uint32_t smu_pcie_arg;<br>
+<br>
+       for (i = 0; i < NUM_LINK_LEVELS; i++) {<br>
+               smu_pcie_arg = (i << 16) |<br>
+                       ((pptable->PcieGenSpeed[i] <= pcie_gen_cap) ? (pptable->PcieGenSpeed[i] << 8) :<br>
+                               (pcie_gen_cap << 8)) | ((pptable->PcieLaneCount[i] <= pcie_width_cap) ?<br>
+                                       pptable->PcieLaneCount[i] : pcie_width_cap);<br>
+               ret = smu_send_smc_msg_with_param(smu,<br>
+                                         SMU_MSG_OverridePcieParameters,<br>
+                                         smu_pcie_arg);<br>
+       }<br>
+<br>
+       return ret;<br>
+}<br>
+<br>
+<br>
 static const struct pptable_funcs vega20_ppt_funcs = {<br>
         .tables_init = vega20_tables_init,<br>
         .alloc_dpm_context = vega20_allocate_dpm_context,<br>
@@ -3177,7 +3199,8 @@ static const struct pptable_funcs vega20_ppt_funcs = {<br>
         .get_fan_speed_percent = vega20_get_fan_speed_percent,<br>
         .get_fan_speed_rpm = vega20_get_fan_speed_rpm,<br>
         .set_watermarks_table = vega20_set_watermarks_table,<br>
-       .get_thermal_temperature_range = vega20_get_thermal_temperature_range<br>
+       .get_thermal_temperature_range = vega20_get_thermal_temperature_range,<br>
+       .update_pcie_parameters = vega20_update_pcie_parameters<br>
 };<br>
 <br>
 void vega20_set_ppt_funcs(struct smu_context *smu)<br>
-- <br>
2.7.4<br>
<br>
_______________________________________________<br>
amd-gfx mailing list<br>
amd-gfx@lists.freedesktop.org<br>
<a href="https://lists.freedesktop.org/mailman/listinfo/amd-gfx">https://lists.freedesktop.org/mailman/listinfo/amd-gfx</a></div>
</span></font></div>
</body>
</html>