All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] drm/amd/powerplay: bug fix for pcie parameters override
@ 2019-10-11 10:33 Kenneth Feng
       [not found] ` <1570790025-8274-1-git-send-email-kenneth.feng-5C7GfCeVMHo@public.gmane.org>
  0 siblings, 1 reply; 4+ messages in thread
From: Kenneth Feng @ 2019-10-11 10:33 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Kenneth Feng

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@amd.com>
---
 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@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] drm/amd/powerplay: bug fix for pcie parameters override
       [not found] ` <1570790025-8274-1-git-send-email-kenneth.feng-5C7GfCeVMHo@public.gmane.org>
@ 2019-10-12  2:06   ` Alex Deucher
  2019-10-14  1:48   ` Quan, Evan
  2019-10-14  2:31   ` Wang, Kevin(Yang)
  2 siblings, 0 replies; 4+ messages in thread
From: Alex Deucher @ 2019-10-12  2:06 UTC (permalink / raw)
  To: Kenneth Feng; +Cc: amd-gfx list

On Fri, Oct 11, 2019 at 6:34 AM Kenneth Feng <kenneth.feng@amd.com> 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@amd.com>

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  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@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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: [PATCH v2] drm/amd/powerplay: bug fix for pcie parameters override
       [not found] ` <1570790025-8274-1-git-send-email-kenneth.feng-5C7GfCeVMHo@public.gmane.org>
  2019-10-12  2:06   ` Alex Deucher
@ 2019-10-14  1:48   ` Quan, Evan
  2019-10-14  2:31   ` Wang, Kevin(Yang)
  2 siblings, 0 replies; 4+ messages in thread
From: Quan, Evan @ 2019-10-14  1:48 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Feng, Kenneth

Reviewed-by: Evan Quan <evan.quan@amd.com>

-----Original Message-----
From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Kenneth Feng
Sent: Friday, October 11, 2019 6:34 PM
To: amd-gfx@lists.freedesktop.org
Cc: Feng, Kenneth <Kenneth.Feng@amd.com>
Subject: [PATCH v2] drm/amd/powerplay: bug fix for pcie parameters override

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@amd.com>
---
 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@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

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] drm/amd/powerplay: bug fix for pcie parameters override
       [not found] ` <1570790025-8274-1-git-send-email-kenneth.feng-5C7GfCeVMHo@public.gmane.org>
  2019-10-12  2:06   ` Alex Deucher
  2019-10-14  1:48   ` Quan, Evan
@ 2019-10-14  2:31   ` Wang, Kevin(Yang)
  2 siblings, 0 replies; 4+ messages in thread
From: Wang, Kevin(Yang) @ 2019-10-14  2:31 UTC (permalink / raw)
  To: Feng, Kenneth, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW


[-- Attachment #1.1: Type: text/plain, Size: 12978 bytes --]

Reviewed-by: Kevin Wang <kevin1.wang-5C7GfCeVMHo@public.gmane.org>

Best Regards,
Kevin
________________________________
From: amd-gfx <amd-gfx-bounces-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org> on behalf of Kenneth Feng <kenneth.feng-5C7GfCeVMHo@public.gmane.org>
Sent: Friday, October 11, 2019 6:33 PM
To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org <amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org>
Cc: Feng, Kenneth <Kenneth.Feng-5C7GfCeVMHo@public.gmane.org>
Subject: [PATCH v2] drm/amd/powerplay: bug fix for pcie parameters override

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-5C7GfCeVMHo@public.gmane.org>
---
 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-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[-- Attachment #1.2: Type: text/html, Size: 24948 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-10-14  2:31 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-11 10:33 [PATCH v2] drm/amd/powerplay: bug fix for pcie parameters override Kenneth Feng
     [not found] ` <1570790025-8274-1-git-send-email-kenneth.feng-5C7GfCeVMHo@public.gmane.org>
2019-10-12  2:06   ` Alex Deucher
2019-10-14  1:48   ` Quan, Evan
2019-10-14  2:31   ` Wang, Kevin(Yang)

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.