parse and print detailed reasons for od table upload failures to
help users understand error causes.

example:
$ echo "0 30 40" | sudo tee fan_curve
$ echo "1 40 30" | sudo tee fan_curve
$ echo "c" | sudo tee fan_curve

kernel log:
[   75.040174] amdgpu 0000:0a:00.0: Failed to upload overdrive table, ret:-5
[   75.040178] amdgpu 0000:0a:00.0: Invalid overdrive table content: 
OD_FAN_CURVE_PWM_ERROR (13)
[   75.040181] amdgpu 0000:0a:00.0: Failed to upload overdrive table!

Signed-off-by: Yang Wang <[email protected]>
---
 .../drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c  | 60 ++++++++++++++++---
 1 file changed, 52 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c 
b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
index 0bad56a44f5c..4fbcb9de7117 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
@@ -2230,17 +2230,61 @@ static void smu_v14_0_2_dump_od_table(struct 
smu_context *smu,
                 od_table->OverDriveTable.FanMode);
 }
 
+#define OD_FAIL_MSG_MAP(msg) \
+       [msg] = #msg
+
+static const char *od_failed_message[] = {
+       OD_FAIL_MSG_MAP(OD_REQUEST_ADVANCED_NOT_SUPPORTED),
+       OD_FAIL_MSG_MAP(OD_UNSUPPORTED_FEATURE),
+       OD_FAIL_MSG_MAP(OD_INVALID_FEATURE_COMBO_ERROR),
+       OD_FAIL_MSG_MAP(OD_GFXCLK_VF_CURVE_OFFSET_ERROR),
+       OD_FAIL_MSG_MAP(OD_VDD_GFX_VMAX_ERROR),
+       OD_FAIL_MSG_MAP(OD_VDD_SOC_VMAX_ERROR),
+       OD_FAIL_MSG_MAP(OD_PPT_ERROR),
+       OD_FAIL_MSG_MAP(OD_FAN_MIN_PWM_ERROR),
+       OD_FAIL_MSG_MAP(OD_FAN_ACOUSTIC_TARGET_ERROR),
+       OD_FAIL_MSG_MAP(OD_FAN_ACOUSTIC_LIMIT_ERROR),
+       OD_FAIL_MSG_MAP(OD_FAN_TARGET_TEMP_ERROR),
+       OD_FAIL_MSG_MAP(OD_FAN_ZERO_RPM_STOP_TEMP_ERROR),
+       OD_FAIL_MSG_MAP(OD_FAN_CURVE_PWM_ERROR),
+       OD_FAIL_MSG_MAP(OD_FAN_CURVE_TEMP_ERROR),
+       OD_FAIL_MSG_MAP(OD_FULL_CTRL_GFXCLK_ERROR),
+       OD_FAIL_MSG_MAP(OD_FULL_CTRL_UCLK_ERROR),
+       OD_FAIL_MSG_MAP(OD_FULL_CTRL_FCLK_ERROR),
+       OD_FAIL_MSG_MAP(OD_FULL_CTRL_VDD_GFX_ERROR),
+       OD_FAIL_MSG_MAP(OD_FULL_CTRL_VDD_SOC_ERROR),
+       OD_FAIL_MSG_MAP(OD_TDC_ERROR),
+       OD_FAIL_MSG_MAP(OD_GFXCLK_ERROR),
+       OD_FAIL_MSG_MAP(OD_UCLK_ERROR),
+       OD_FAIL_MSG_MAP(OD_FCLK_ERROR),
+       OD_FAIL_MSG_MAP(OD_OP_TEMP_ERROR),
+       OD_FAIL_MSG_MAP(OD_OP_GFX_EDC_ERROR),
+       OD_FAIL_MSG_MAP(OD_OP_GFX_PCC_ERROR),
+       OD_FAIL_MSG_MAP(OD_POWER_FEATURE_CTRL_ERROR),
+};
+
 static int smu_v14_0_2_upload_overdrive_table(struct smu_context *smu,
                                              OverDriveTableExternal_t 
*od_table)
 {
-       int ret;
-       ret = smu_cmn_update_table(smu,
-                                  SMU_TABLE_OVERDRIVE,
-                                  0,
-                                  (void *)od_table,
-                                  true);
-       if (ret)
-               dev_err(smu->adev->dev, "Failed to upload overdrive table!\n");
+       uint32_t read_arg = 0;
+       int ret, od_faile_type;
+
+       ret = smu_cmn_update_table_read_arg(smu,
+                                           SMU_TABLE_OVERDRIVE,
+                                           0,
+                                           (void *)od_table,
+                                           &read_arg,
+                                           true);
+       if (ret) {
+               dev_err(smu->adev->dev, "Failed to upload overdrive table, 
ret:%d\n", ret);
+               if ((read_arg & 0xff) == TABLE_TRANSFER_FAILED) {
+                       od_faile_type = read_arg >> 16;
+                       dev_err(smu->adev->dev, "Invalid overdrive table 
content: %s (%d)\n",
+                               od_faile_type < ARRAY_SIZE(od_failed_message) ?
+                               od_failed_message[od_faile_type] : "unknown",
+                               od_faile_type);
+               }
+       }
 
        return ret;
 }
-- 
2.47.3

Reply via email to