drm/amd/powerplay: do proper cleanups on hw_fini
authorEvan Quan <evan.quan@amd.com>
Mon, 2 Sep 2019 04:37:23 +0000 (12:37 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 13 Sep 2019 22:36:52 +0000 (17:36 -0500)
These are needed for smu_reset support.

Signed-off-by: Evan Quan <evan.quan@amd.com>
Reviewed-by: Jack Gui <Jack.Gui@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
drivers/gpu/drm/amd/powerplay/smu_v11_0.c

index ceaf54d70103eee9fca3347b575512acac6f171f..82a8298b70407a61a073eb8a233ffc6349974fe9 100644 (file)
@@ -1283,6 +1283,11 @@ failed:
        return ret;
 }
 
+static int smu_stop_dpms(struct smu_context *smu)
+{
+       return smu_send_smc_msg(smu, SMU_MSG_DisableAllSmuFeatures);
+}
+
 static int smu_hw_fini(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
@@ -1295,6 +1300,18 @@ static int smu_hw_fini(void *handle)
                smu_powergate_vcn(&adev->smu, true);
        }
 
+       ret = smu_stop_thermal_control(smu);
+       if (ret) {
+               pr_warn("Fail to stop thermal control!\n");
+               return ret;
+       }
+
+       ret = smu_stop_dpms(smu);
+       if (ret) {
+               pr_warn("Fail to stop Dpms!\n");
+               return ret;
+       }
+
        kfree(table_context->driver_pptable);
        table_context->driver_pptable = NULL;
 
index b19224cb6d6de0f4ddfd8bfea6a5548ff7ec8d8a..8e4b0ad247128e1cabcf90d21721efa5fedce0f9 100644 (file)
@@ -498,6 +498,7 @@ struct smu_funcs
        int (*get_current_clk_freq)(struct smu_context *smu, enum smu_clk_type clk_id, uint32_t *value);
        int (*init_max_sustainable_clocks)(struct smu_context *smu);
        int (*start_thermal_control)(struct smu_context *smu);
+       int (*stop_thermal_control)(struct smu_context *smu);
        int (*read_sensor)(struct smu_context *smu, enum amd_pp_sensors sensor,
                           void *data, uint32_t *size);
        int (*set_deep_sleep_dcefclk)(struct smu_context *smu, uint32_t clk);
@@ -647,6 +648,8 @@ struct smu_funcs
        ((smu)->ppt_funcs->set_thermal_fan_table ? (smu)->ppt_funcs->set_thermal_fan_table((smu)) : 0)
 #define smu_start_thermal_control(smu) \
        ((smu)->funcs->start_thermal_control? (smu)->funcs->start_thermal_control((smu)) : 0)
+#define smu_stop_thermal_control(smu) \
+       ((smu)->funcs->stop_thermal_control? (smu)->funcs->stop_thermal_control((smu)) : 0)
 #define smu_read_sensor(smu, sensor, data, size) \
        ((smu)->ppt_funcs->read_sensor? (smu)->ppt_funcs->read_sensor((smu), (sensor), (data), (size)) : 0)
 #define smu_smc_read_sensor(smu, sensor, data, size) \
index c5257ae3188a3fe3c2cf7e4fe51961a190ca9372..68740d4b66a0ee2672c7b7502c8068350d896aa8 100644 (file)
@@ -1212,6 +1212,15 @@ static int smu_v11_0_start_thermal_control(struct smu_context *smu)
        return ret;
 }
 
+static int smu_v11_0_stop_thermal_control(struct smu_context *smu)
+{
+       struct amdgpu_device *adev = smu->adev;
+
+       WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_ENA, 0);
+
+       return 0;
+}
+
 static uint16_t convert_to_vddc(uint8_t vid)
 {
        return (uint16_t) ((6200 - (vid * 25)) / SMU11_VOLTAGE_SCALE);
@@ -1787,6 +1796,7 @@ static const struct smu_funcs smu_v11_0_funcs = {
        .get_current_clk_freq = smu_v11_0_get_current_clk_freq,
        .init_max_sustainable_clocks = smu_v11_0_init_max_sustainable_clocks,
        .start_thermal_control = smu_v11_0_start_thermal_control,
+       .stop_thermal_control = smu_v11_0_stop_thermal_control,
        .read_sensor = smu_v11_0_read_sensor,
        .set_deep_sleep_dcefclk = smu_v11_0_set_deep_sleep_dcefclk,
        .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,