diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0430-drm-amd-powerplay-enable-fan-RPM-and-pwm-settings-V2.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0430-drm-amd-powerplay-enable-fan-RPM-and-pwm-settings-V2.patch | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0430-drm-amd-powerplay-enable-fan-RPM-and-pwm-settings-V2.patch b/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0430-drm-amd-powerplay-enable-fan-RPM-and-pwm-settings-V2.patch new file mode 100644 index 00000000..f1ebab63 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0430-drm-amd-powerplay-enable-fan-RPM-and-pwm-settings-V2.patch @@ -0,0 +1,331 @@ +From ea9b575c2553a552af3d26cc166b818f496ff1ba Mon Sep 17 00:00:00 2001 +From: Evan Quan <evan.quan@amd.com> +Date: Tue, 18 Sep 2018 18:04:44 +0800 +Subject: [PATCH 0430/2940] drm/amd/powerplay: enable fan RPM and pwm settings + V2 + +Manual fan RPM and pwm setting on vega20 are +available now. + +V2: correct the register for fan speed setting and + avoid divide-by-zero + +Change-Id: Iad45a169d6984acc091c4efaf46973619fe43a29 +Signed-off-by: Evan Quan <evan.quan@amd.com> +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> +Reviewed-by: Rex Zhu <Rex.Zhu@amd.com> +--- + .../include/asic_reg/thm/thm_11_0_2_offset.h | 12 ++ + .../include/asic_reg/thm/thm_11_0_2_sh_mask.h | 10 ++ + .../drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 27 ++++ + .../drm/amd/powerplay/hwmgr/vega20_thermal.c | 151 +++++++++++++++++- + .../drm/amd/powerplay/hwmgr/vega20_thermal.h | 11 +- + 5 files changed, 207 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_offset.h b/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_offset.h +index 510ec3c70626..a9eb57a53e59 100644 +--- a/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_offset.h ++++ b/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_offset.h +@@ -26,6 +26,18 @@ + #define mmCG_MULT_THERMAL_STATUS 0x005f + #define mmCG_MULT_THERMAL_STATUS_BASE_IDX 0 + ++#define mmCG_FDO_CTRL0 0x0067 ++#define mmCG_FDO_CTRL0_BASE_IDX 0 ++ ++#define mmCG_FDO_CTRL1 0x0068 ++#define mmCG_FDO_CTRL1_BASE_IDX 0 ++ ++#define mmCG_FDO_CTRL2 0x0069 ++#define mmCG_FDO_CTRL2_BASE_IDX 0 ++ ++#define mmCG_TACH_CTRL 0x006a ++#define mmCG_TACH_CTRL_BASE_IDX 0 ++ + #define mmTHM_THERMAL_INT_ENA 0x000a + #define mmTHM_THERMAL_INT_ENA_BASE_IDX 0 + #define mmTHM_THERMAL_INT_CTRL 0x000b +diff --git a/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_sh_mask.h +index f69533fa6abf..d130d92aee19 100644 +--- a/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_sh_mask.h ++++ b/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_sh_mask.h +@@ -28,6 +28,16 @@ + #define CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT 0x9 + #define CG_MULT_THERMAL_STATUS__ASIC_MAX_TEMP_MASK 0x000001FFL + #define CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK 0x0003FE00L ++#define CG_FDO_CTRL2__TMIN__SHIFT 0x0 ++#define CG_FDO_CTRL2__TMIN_MASK 0x000000FFL ++#define CG_FDO_CTRL2__FDO_PWM_MODE__SHIFT 0xb ++#define CG_FDO_CTRL2__FDO_PWM_MODE_MASK 0x00003800L ++#define CG_FDO_CTRL1__FMAX_DUTY100__SHIFT 0x0 ++#define CG_FDO_CTRL1__FMAX_DUTY100_MASK 0x000000FFL ++#define CG_FDO_CTRL0__FDO_STATIC_DUTY__SHIFT 0x0 ++#define CG_FDO_CTRL0__FDO_STATIC_DUTY_MASK 0x000000FFL ++#define CG_TACH_CTRL__TARGET_PERIOD__SHIFT 0x3 ++#define CG_TACH_CTRL__TARGET_PERIOD_MASK 0xFFFFFFF8L + + //THM_THERMAL_INT_ENA + #define THM_THERMAL_INT_ENA__THERM_INTH_SET__SHIFT 0x0 +diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +index 6ece7d724a5b..ee38ed56dd51 100644 +--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c ++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +@@ -2289,6 +2289,25 @@ static uint32_t vega20_get_fan_control_mode(struct pp_hwmgr *hwmgr) + return AMD_FAN_CTRL_AUTO; + } + ++static void vega20_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode) ++{ ++ switch (mode) { ++ case AMD_FAN_CTRL_NONE: ++ vega20_fan_ctrl_set_fan_speed_percent(hwmgr, 100); ++ break; ++ case AMD_FAN_CTRL_MANUAL: ++ if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl)) ++ vega20_fan_ctrl_stop_smc_fan_control(hwmgr); ++ break; ++ case AMD_FAN_CTRL_AUTO: ++ if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl)) ++ vega20_fan_ctrl_start_smc_fan_control(hwmgr); ++ break; ++ default: ++ break; ++ } ++} ++ + static int vega20_get_dal_power_level(struct pp_hwmgr *hwmgr, + struct amd_pp_simple_clock_info *info) + { +@@ -3452,12 +3471,20 @@ static const struct pp_hwmgr_func vega20_hwmgr_funcs = { + .disable_smc_firmware_ctf = + vega20_thermal_disable_alert, + /* fan control related */ ++ .get_fan_speed_percent = ++ vega20_fan_ctrl_get_fan_speed_percent, ++ .set_fan_speed_percent = ++ vega20_fan_ctrl_set_fan_speed_percent, + .get_fan_speed_info = + vega20_fan_ctrl_get_fan_speed_info, + .get_fan_speed_rpm = + vega20_fan_ctrl_get_fan_speed_rpm, ++ .set_fan_speed_rpm = ++ vega20_fan_ctrl_set_fan_speed_rpm, + .get_fan_control_mode = + vega20_get_fan_control_mode, ++ .set_fan_control_mode = ++ vega20_set_fan_control_mode, + /* smu memory related */ + .notify_cac_buffer_info = + vega20_notify_cac_buffer_info, +diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c +index 1c951a5d827d..ede54e87e287 100644 +--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c ++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c +@@ -29,6 +29,78 @@ + #include "soc15_common.h" + #include "pp_debug.h" + ++static int vega20_disable_fan_control_feature(struct pp_hwmgr *hwmgr) ++{ ++ struct vega20_hwmgr *data = hwmgr->backend; ++ int ret = 0; ++ ++ if (data->smu_features[GNLD_FAN_CONTROL].supported) { ++ ret = vega20_enable_smc_features( ++ hwmgr, false, ++ data->smu_features[GNLD_FAN_CONTROL]. ++ smu_feature_bitmap); ++ PP_ASSERT_WITH_CODE(!ret, ++ "Disable FAN CONTROL feature Failed!", ++ return ret); ++ data->smu_features[GNLD_FAN_CONTROL].enabled = false; ++ } ++ ++ return ret; ++} ++ ++int vega20_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr) ++{ ++ struct vega20_hwmgr *data = hwmgr->backend; ++ ++ if (data->smu_features[GNLD_FAN_CONTROL].supported) ++ return vega20_disable_fan_control_feature(hwmgr); ++ ++ return 0; ++} ++ ++static int vega20_enable_fan_control_feature(struct pp_hwmgr *hwmgr) ++{ ++ struct vega20_hwmgr *data = hwmgr->backend; ++ int ret = 0; ++ ++ if (data->smu_features[GNLD_FAN_CONTROL].supported) { ++ ret = vega20_enable_smc_features( ++ hwmgr, true, ++ data->smu_features[GNLD_FAN_CONTROL]. ++ smu_feature_bitmap); ++ PP_ASSERT_WITH_CODE(!ret, ++ "Enable FAN CONTROL feature Failed!", ++ return ret); ++ data->smu_features[GNLD_FAN_CONTROL].enabled = true; ++ } ++ ++ return ret; ++} ++ ++int vega20_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr) ++{ ++ struct vega20_hwmgr *data = hwmgr->backend; ++ ++ if (data->smu_features[GNLD_FAN_CONTROL].supported) ++ return vega20_enable_fan_control_feature(hwmgr); ++ ++ return 0; ++} ++ ++static int vega20_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode) ++{ ++ struct amdgpu_device *adev = hwmgr->adev; ++ ++ WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2, ++ REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2), ++ CG_FDO_CTRL2, TMIN, 0)); ++ WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2, ++ REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2), ++ CG_FDO_CTRL2, FDO_PWM_MODE, mode)); ++ ++ return 0; ++} ++ + static int vega20_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm) + { + int ret = 0; +@@ -42,12 +114,62 @@ static int vega20_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm) + return 0; + } + ++int vega20_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr, ++ uint32_t *speed) ++{ ++ struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); ++ PPTable_t *pp_table = &(data->smc_state_table.pp_table); ++ uint32_t current_rpm, percent = 0; ++ int ret = 0; ++ ++ ret = vega20_get_current_rpm(hwmgr, ¤t_rpm); ++ if (ret) ++ return ret; ++ ++ percent = current_rpm * 100 / pp_table->FanMaximumRpm; ++ ++ *speed = percent > 100 ? 100 : percent; ++ ++ return 0; ++} ++ ++int vega20_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr, ++ uint32_t speed) ++{ ++ struct amdgpu_device *adev = hwmgr->adev; ++ uint32_t duty100; ++ uint32_t duty; ++ uint64_t tmp64; ++ ++ if (speed > 100) ++ speed = 100; ++ ++ if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl)) ++ vega20_fan_ctrl_stop_smc_fan_control(hwmgr); ++ ++ duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1), ++ CG_FDO_CTRL1, FMAX_DUTY100); ++ ++ if (duty100 == 0) ++ return -EINVAL; ++ ++ tmp64 = (uint64_t)speed * duty100; ++ do_div(tmp64, 100); ++ duty = (uint32_t)tmp64; ++ ++ WREG32_SOC15(THM, 0, mmCG_FDO_CTRL0, ++ REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL0), ++ CG_FDO_CTRL0, FDO_STATIC_DUTY, duty)); ++ ++ return vega20_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC); ++} ++ + int vega20_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr, + struct phm_fan_speed_info *fan_speed_info) + { + memset(fan_speed_info, 0, sizeof(*fan_speed_info)); +- fan_speed_info->supports_percent_read = false; +- fan_speed_info->supports_percent_write = false; ++ fan_speed_info->supports_percent_read = true; ++ fan_speed_info->supports_percent_write = true; + fan_speed_info->supports_rpm_read = true; + fan_speed_info->supports_rpm_write = true; + +@@ -61,6 +183,31 @@ int vega20_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed) + return vega20_get_current_rpm(hwmgr, speed); + } + ++int vega20_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed) ++{ ++ struct amdgpu_device *adev = hwmgr->adev; ++ uint32_t tach_period, crystal_clock_freq; ++ int result = 0; ++ ++ if (!speed) ++ return -EINVAL; ++ ++ if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl)) { ++ result = vega20_fan_ctrl_stop_smc_fan_control(hwmgr); ++ if (result) ++ return result; ++ } ++ ++ crystal_clock_freq = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev); ++ tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed); ++ WREG32_SOC15(THM, 0, mmCG_TACH_CTRL, ++ REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_TACH_CTRL), ++ CG_TACH_CTRL, TARGET_PERIOD, ++ tach_period)); ++ ++ return vega20_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC_RPM); ++} ++ + /** + * Reads the remote temperature from the SIslands thermal controller. + * +diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.h +index 2a6d49fec4e0..2d1769bbd24e 100644 +--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.h ++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.h +@@ -50,15 +50,22 @@ struct vega20_temperature { + #define FDO_PWM_MODE_STATIC_RPM 5 + + extern int vega20_thermal_get_temperature(struct pp_hwmgr *hwmgr); +-extern int vega20_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr); + extern int vega20_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr, + struct phm_fan_speed_info *fan_speed_info); +-extern int vega20_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr); + extern int vega20_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, + uint32_t *speed); ++extern int vega20_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, ++ uint32_t speed); ++extern int vega20_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr, ++ uint32_t *speed); ++extern int vega20_fan_ctrl_set_fan_speed_percent(struct pp_hwmgr *hwmgr, ++ uint32_t speed); ++extern int vega20_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr); ++extern int vega20_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr); + extern int vega20_thermal_disable_alert(struct pp_hwmgr *hwmgr); + extern int vega20_start_thermal_controller(struct pp_hwmgr *hwmgr, + struct PP_TemperatureRange *range); ++extern int vega20_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr); + + #endif + +-- +2.17.1 + |