drm/amd/powerplay: implement stop dpm task for vega10.
authorRex Zhu <Rex.Zhu@amd.com>
Thu, 27 Apr 2017 07:48:56 +0000 (15:48 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 28 Apr 2017 21:33:16 +0000 (17:33 -0400)
Add functions to disable dpm for S3/S4.

Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Huang Rui <ray.huang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.h
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.h

index 5e3e89be9fb697ca92a78b8f029c56740950f07d..68eae529df5098204fd2e4e8fe4d5ea8b9caeec0 100644 (file)
@@ -2420,6 +2420,26 @@ static int vega10_enable_thermal_protection(struct pp_hwmgr *hwmgr)
        return 0;
 }
 
+static int vega10_disable_thermal_protection(struct pp_hwmgr *hwmgr)
+{
+       struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
+
+       if (data->smu_features[GNLD_THERMAL].supported) {
+               if (!data->smu_features[GNLD_THERMAL].enabled)
+                       pr_info("THERMAL Feature Already disabled!");
+
+               PP_ASSERT_WITH_CODE(
+                               !vega10_enable_smc_features(hwmgr->smumgr,
+                               false,
+                               data->smu_features[GNLD_THERMAL].smu_feature_bitmap),
+                               "disable THERMAL Feature Failed!",
+                               return -1);
+               data->smu_features[GNLD_THERMAL].enabled = false;
+       }
+
+       return 0;
+}
+
 static int vega10_enable_vrhot_feature(struct pp_hwmgr *hwmgr)
 {
        struct vega10_hwmgr *data =
@@ -2498,6 +2518,37 @@ static int vega10_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr)
        return 0;
 }
 
+static int vega10_stop_dpm(struct pp_hwmgr *hwmgr, uint32_t bitmap)
+{
+       struct vega10_hwmgr *data =
+                       (struct vega10_hwmgr *)(hwmgr->backend);
+       uint32_t i, feature_mask = 0;
+
+
+       if(data->smu_features[GNLD_LED_DISPLAY].supported == true){
+               PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr->smumgr,
+                               true, data->smu_features[GNLD_LED_DISPLAY].smu_feature_bitmap),
+               "Attempt to Enable LED DPM feature Failed!", return -EINVAL);
+               data->smu_features[GNLD_LED_DISPLAY].enabled = true;
+       }
+
+       for (i = 0; i < GNLD_DPM_MAX; i++) {
+               if (data->smu_features[i].smu_feature_bitmap & bitmap) {
+                       if (data->smu_features[i].supported) {
+                               if (data->smu_features[i].enabled) {
+                                       feature_mask |= data->smu_features[i].
+                                                       smu_feature_bitmap;
+                                       data->smu_features[i].enabled = false;
+                               }
+                       }
+               }
+       }
+
+       vega10_enable_smc_features(hwmgr->smumgr, false, feature_mask);
+
+       return 0;
+}
+
 /**
  * @brief Tell SMC to enabled the supported DPMs.
  *
@@ -4356,11 +4407,55 @@ vega10_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmg
        return is_update_required;
 }
 
+static int vega10_disable_dpm_tasks(struct pp_hwmgr *hwmgr)
+{
+       int tmp_result, result = 0;
+
+       tmp_result = (vega10_is_dpm_running(hwmgr)) ? 0 : -1;
+       PP_ASSERT_WITH_CODE(tmp_result == 0,
+                       "DPM is not running right now, no need to disable DPM!",
+                       return 0);
+
+       if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+                       PHM_PlatformCaps_ThermalController))
+               vega10_disable_thermal_protection(hwmgr);
+
+       tmp_result = vega10_disable_power_containment(hwmgr);
+       PP_ASSERT_WITH_CODE((tmp_result == 0),
+                       "Failed to disable power containment!", result = tmp_result);
+
+       tmp_result = vega10_avfs_enable(hwmgr, false);
+       PP_ASSERT_WITH_CODE((tmp_result == 0),
+                       "Failed to disable AVFS!", result = tmp_result);
+
+       tmp_result = vega10_stop_dpm(hwmgr, SMC_DPM_FEATURES);
+       PP_ASSERT_WITH_CODE((tmp_result == 0),
+                       "Failed to stop DPM!", result = tmp_result);
+
+       return result;
+}
+
+static int vega10_power_off_asic(struct pp_hwmgr *hwmgr)
+{
+       struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
+       int result;
+
+       result = vega10_disable_dpm_tasks(hwmgr);
+       PP_ASSERT_WITH_CODE((0 == result),
+                       "[disable_dpm_tasks] Failed to disable DPM!",
+                       );
+       data->water_marks_bitmap &= ~(WaterMarksLoaded);
+
+       return result;
+}
+
+
 static const struct pp_hwmgr_func vega10_hwmgr_funcs = {
        .backend_init = vega10_hwmgr_backend_init,
        .backend_fini = vega10_hwmgr_backend_fini,
        .asic_setup = vega10_setup_asic_task,
        .dynamic_state_management_enable = vega10_enable_dpm_tasks,
+       .dynamic_state_management_disable = vega10_disable_dpm_tasks,
        .get_num_of_pp_table_entries =
                        vega10_get_number_of_powerplay_table_entries,
        .get_power_state_size = vega10_get_power_state_size,
@@ -4400,6 +4495,8 @@ static const struct pp_hwmgr_func vega10_hwmgr_funcs = {
        .check_states_equal = vega10_check_states_equal,
        .check_smc_update_required_for_display_configuration =
                        vega10_check_smc_update_required_for_display_configuration,
+       .power_off_asic = vega10_power_off_asic,
+       .disable_smc_firmware_ctf = vega10_thermal_disable_alert,
 };
 
 int vega10_hwmgr_init(struct pp_hwmgr *hwmgr)
index f1e244cd2370bee568db2b889a0b0030aad7576a..692f752fbb27643b93e4efd13601fa6421950f19 100644 (file)
@@ -113,6 +113,29 @@ int vega10_enable_power_containment(struct pp_hwmgr *hwmgr)
        return result;
 }
 
+int vega10_disable_power_containment(struct pp_hwmgr *hwmgr)
+{
+       struct vega10_hwmgr *data =
+                       (struct vega10_hwmgr *)(hwmgr->backend);
+
+       if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+                       PHM_PlatformCaps_PowerContainment)) {
+               if (data->smu_features[GNLD_PPT].supported)
+                       PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr->smumgr,
+                                       false, data->smu_features[GNLD_PPT].smu_feature_bitmap),
+                                       "Attempt to disable PPT feature Failed!",
+                                       data->smu_features[GNLD_PPT].supported = false);
+
+               if (data->smu_features[GNLD_TDC].supported)
+                       PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr->smumgr,
+                                       false, data->smu_features[GNLD_TDC].smu_feature_bitmap),
+                                       "Attempt to disable PPT feature Failed!",
+                                       data->smu_features[GNLD_TDC].supported = false);
+       }
+
+       return 0;
+}
+
 static int vega10_set_overdrive_target_percentage(struct pp_hwmgr *hwmgr,
                uint32_t adjust_percent)
 {
index d9662bf4a4b4f9d9bed26f204d504667df90f5e7..9ecaa27c0bb547e1c72707c4a562f19123b7ff76 100644 (file)
@@ -60,6 +60,7 @@ int vega10_enable_smc_cac(struct pp_hwmgr *hwmgr);
 int vega10_enable_power_containment(struct pp_hwmgr *hwmgr);
 int vega10_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n);
 int vega10_power_control_set_level(struct pp_hwmgr *hwmgr);
+int vega10_disable_power_containment(struct pp_hwmgr *hwmgr);
 
 #endif  /* _VEGA10_POWERTUNE_H_ */
 
index f4d77b62e1ba8653e7508387d6465f37f03451ed..7062ec8cc4ac8cb928aaf2ff9c8ff3b30e805c13 100644 (file)
@@ -501,7 +501,7 @@ static int vega10_thermal_enable_alert(struct pp_hwmgr *hwmgr)
 * Disable thermal alerts on the RV770 thermal controller.
 * @param    hwmgr The address of the hardware manager.
 */
-static int vega10_thermal_disable_alert(struct pp_hwmgr *hwmgr)
+int vega10_thermal_disable_alert(struct pp_hwmgr *hwmgr)
 {
        struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
 
index 8036808ec42123d307b0a58455057e2f178196a0..70c1d22b3d7df4f565a655b4e38b563d2b23e7ec 100644 (file)
@@ -78,6 +78,7 @@ extern int vega10_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr,
                uint32_t *speed);
 extern int vega10_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr);
 extern uint32_t smu7_get_xclk(struct pp_hwmgr *hwmgr);
+extern int vega10_thermal_disable_alert(struct pp_hwmgr *hwmgr);
 
 #endif