drm/amd/pm: Add SMU 13.0.6 support
[linux-2.6-block.git] / drivers / gpu / drm / amd / pm / swsmu / amdgpu_smu.c
index ec52830dde245544982263df3ede6c3177bce1cf..b5d64749990e1aeddf6ac69361a92c64cc6af140 100644 (file)
@@ -40,6 +40,7 @@
 #include "smu_v13_0_0_ppt.h"
 #include "smu_v13_0_4_ppt.h"
 #include "smu_v13_0_5_ppt.h"
+#include "smu_v13_0_6_ppt.h"
 #include "smu_v13_0_7_ppt.h"
 #include "amd_pcie.h"
 
@@ -609,6 +610,11 @@ static int smu_set_funcs(struct amdgpu_device *adev)
        case IP_VERSION(13, 0, 10):
                smu_v13_0_0_set_ppt_funcs(smu);
                break;
+       case IP_VERSION(13, 0, 6):
+               smu_v13_0_6_set_ppt_funcs(smu);
+               /* Enable pp_od_clk_voltage node */
+               smu->od_enabled = true;
+               break;
        case IP_VERSION(13, 0, 7):
                smu_v13_0_7_set_ppt_funcs(smu);
                break;
@@ -904,9 +910,8 @@ static int smu_alloc_dummy_read_table(struct smu_context *smu)
        struct amdgpu_device *adev = smu->adev;
        int ret = 0;
 
-       dummy_read_1_table->size = 0x40000;
-       dummy_read_1_table->align = PAGE_SIZE;
-       dummy_read_1_table->domain = AMDGPU_GEM_DOMAIN_VRAM;
+       if (!dummy_read_1_table->size)
+               return 0;
 
        ret = amdgpu_bo_create_kernel(adev,
                                      dummy_read_1_table->size,
@@ -1203,10 +1208,17 @@ static int smu_smc_hw_setup(struct smu_context *smu)
                return ret;
        }
 
-       ret = smu_setup_pptable(smu);
-       if (ret) {
-               dev_err(adev->dev, "Failed to setup pptable!\n");
-               return ret;
+       /*
+        * It is assumed the pptable used before runpm is same as
+        * the one used afterwards. Thus, we can reuse the stored
+        * copy and do not need to resetup the pptable again.
+        */
+       if (!adev->in_runpm) {
+               ret = smu_setup_pptable(smu);
+               if (ret) {
+                       dev_err(adev->dev, "Failed to setup pptable!\n");
+                       return ret;
+               }
        }
 
        /* smu_dump_pptable(smu); */
@@ -1497,6 +1509,20 @@ static int smu_disable_dpms(struct smu_context *smu)
                }
        }
 
+       /*
+        * For SMU 13.0.4/11, PMFW will handle the features disablement properly
+        * for gpu reset case. Driver involvement is unnecessary.
+        */
+       if (amdgpu_in_reset(adev)) {
+               switch (adev->ip_versions[MP1_HWIP][0]) {
+               case IP_VERSION(13, 0, 4):
+               case IP_VERSION(13, 0, 11):
+                       return 0;
+               default:
+                       break;
+               }
+       }
+
        /*
         * For gpu reset, runpm and hibernation through BACO,
         * BACO feature has to be kept enabled.
@@ -2512,6 +2538,28 @@ unlock:
        return ret;
 }
 
+static int smu_get_apu_thermal_limit(void *handle, uint32_t *limit)
+{
+       int ret = -EINVAL;
+       struct smu_context *smu = handle;
+
+       if (smu->ppt_funcs && smu->ppt_funcs->get_apu_thermal_limit)
+               ret = smu->ppt_funcs->get_apu_thermal_limit(smu, limit);
+
+       return ret;
+}
+
+static int smu_set_apu_thermal_limit(void *handle, uint32_t limit)
+{
+       int ret = -EINVAL;
+       struct smu_context *smu = handle;
+
+       if (smu->ppt_funcs && smu->ppt_funcs->set_apu_thermal_limit)
+               ret = smu->ppt_funcs->set_apu_thermal_limit(smu, limit);
+
+       return ret;
+}
+
 static int smu_get_power_profile_mode(void *handle, char *buf)
 {
        struct smu_context *smu = handle;
@@ -2845,6 +2893,23 @@ static int smu_mode2_reset(void *handle)
        return ret;
 }
 
+static int smu_enable_gfx_features(void *handle)
+{
+       struct smu_context *smu = handle;
+       int ret = 0;
+
+       if (!smu->pm_enabled)
+               return -EOPNOTSUPP;
+
+       if (smu->ppt_funcs->enable_gfx_features)
+               ret = smu->ppt_funcs->enable_gfx_features(smu);
+
+       if (ret)
+               dev_err(smu->adev->dev, "enable gfx features failed!\n");
+
+       return ret;
+}
+
 static int smu_get_max_sustainable_clocks_by_dc(void *handle,
                                                struct pp_smu_nv_clock_table *max_clocks)
 {
@@ -2996,6 +3061,8 @@ static const struct amd_pm_funcs swsmu_pm_funcs = {
        .emit_clock_levels       = smu_emit_ppclk_levels,
        .force_performance_level = smu_force_performance_level,
        .read_sensor             = smu_read_sensor,
+       .get_apu_thermal_limit       = smu_get_apu_thermal_limit,
+       .set_apu_thermal_limit       = smu_set_apu_thermal_limit,
        .get_performance_level   = smu_get_performance_level,
        .get_current_power_state = smu_get_current_power_state,
        .get_fan_speed_rpm       = smu_get_fan_speed_rpm,
@@ -3029,6 +3096,7 @@ static const struct amd_pm_funcs swsmu_pm_funcs = {
        .get_ppfeature_status             = smu_sys_get_pp_feature_mask,
        .set_ppfeature_status             = smu_sys_set_pp_feature_mask,
        .asic_reset_mode_2                = smu_mode2_reset,
+       .asic_reset_enable_gfx_features   = smu_enable_gfx_features,
        .set_df_cstate                    = smu_set_df_cstate,
        .set_xgmi_pstate                  = smu_set_xgmi_pstate,
        .get_gpu_metrics                  = smu_sys_get_gpu_metrics,