diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1480-drm-amd-powerplay-implement-pwm1-hwmon-interface-for.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/1480-drm-amd-powerplay-implement-pwm1-hwmon-interface-for.patch | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1480-drm-amd-powerplay-implement-pwm1-hwmon-interface-for.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1480-drm-amd-powerplay-implement-pwm1-hwmon-interface-for.patch new file mode 100644 index 00000000..6f541b4d --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1480-drm-amd-powerplay-implement-pwm1-hwmon-interface-for.patch @@ -0,0 +1,205 @@ +From 9aa48e24402e14e3f0c63d246271adac95e3f88c Mon Sep 17 00:00:00 2001 +From: Chengming Gui <Jack.Gui@amd.com> +Date: Thu, 24 Jan 2019 18:39:04 +0800 +Subject: [PATCH 1480/2940] drm/amd/powerplay: implement pwm1 hwmon interface + for SMU11 (v2) + +added main functions: + get_fan_speed_percent + set_fan_speed_percent. +added dependent functions: + smc_fan_control + set_fan_static_mode + get_fan_speed_percent + +v2: fix coding style issue + +Signed-off-by: Chengming Gui <Jack.Gui@amd.com> +Reviewed-by: Huang Rui <ray.huang@amd.com> +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 18 +++- + .../gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 9 ++ + drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 89 +++++++++++++++++++ + 3 files changed, 112 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +index c3508a7c8bfd..284d28acb8c1 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +@@ -1444,8 +1444,10 @@ static ssize_t amdgpu_hwmon_set_pwm1(struct device *dev, + if ((adev->flags & AMD_IS_PX) && + (adev->ddev->switch_power_state != DRM_SWITCH_POWER_ON)) + return -EINVAL; +- +- pwm_mode = amdgpu_dpm_get_fan_control_mode(adev); ++ if (is_support_sw_smu(adev)) ++ pwm_mode = smu_get_fan_control_mode(&adev->smu); ++ else ++ pwm_mode = amdgpu_dpm_get_fan_control_mode(adev); + if (pwm_mode != AMD_FAN_CTRL_MANUAL) { + pr_info("manual fan speed control should be enabled first\n"); + return -EINVAL; +@@ -1457,7 +1459,11 @@ static ssize_t amdgpu_hwmon_set_pwm1(struct device *dev, + + value = (value * 100) / 255; + +- if (adev->powerplay.pp_funcs->set_fan_speed_percent) { ++ if (is_support_sw_smu(adev)) { ++ err = smu_set_fan_speed_percent(&adev->smu, value); ++ if (err) ++ return err; ++ } else if (adev->powerplay.pp_funcs->set_fan_speed_percent) { + err = amdgpu_dpm_set_fan_speed_percent(adev, value); + if (err) + return err; +@@ -1479,7 +1485,11 @@ static ssize_t amdgpu_hwmon_get_pwm1(struct device *dev, + (adev->ddev->switch_power_state != DRM_SWITCH_POWER_ON)) + return -EINVAL; + +- if (adev->powerplay.pp_funcs->get_fan_speed_percent) { ++ if (is_support_sw_smu(adev)) { ++ err = smu_get_fan_speed_percent(&adev->smu, &speed); ++ if (err) ++ return err; ++ } else if (adev->powerplay.pp_funcs->get_fan_speed_percent) { + err = amdgpu_dpm_get_fan_speed_percent(adev, &speed); + if (err) + return err; +diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +index d49bdee76f0e..f94d09db9305 100644 +--- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h ++++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +@@ -532,6 +532,9 @@ struct smu_funcs + uint32_t (*get_sclk)(struct smu_context *smu, bool low); + uint32_t (*get_mclk)(struct smu_context *smu, bool low); + int (*get_current_rpm)(struct smu_context *smu, uint32_t *speed); ++ uint32_t (*get_fan_control_mode)(struct smu_context *smu); ++ int (*get_fan_speed_percent)(struct smu_context *smu, uint32_t *speed); ++ int (*set_fan_speed_percent)(struct smu_context *smu, uint32_t speed); + }; + + #define smu_init_microcode(smu) \ +@@ -664,6 +667,12 @@ struct smu_funcs + ((smu)->ppt_funcs->get_profiling_clk_mask ? (smu)->ppt_funcs->get_profiling_clk_mask((smu), (level), (sclk_mask), (mclk_mask), (soc_mask)) : 0) + #define smu_set_cpu_power_state(smu) \ + ((smu)->ppt_funcs->set_cpu_power_state ? (smu)->ppt_funcs->set_cpu_power_state((smu)) : 0) ++#define smu_get_fan_control_mode(smu) \ ++ ((smu)->funcs->get_fan_control_mode ? (smu)->funcs->get_fan_control_mode((smu)) : 0) ++#define smu_get_fan_speed_percent(smu, speed) \ ++ ((smu)->funcs->get_fan_speed_percent ? (smu)->funcs->get_fan_speed_percent((smu), (speed)) : 0) ++#define smu_set_fan_speed_percent(smu, speed) \ ++ ((smu)->funcs->set_fan_speed_percent ? (smu)->funcs->set_fan_speed_percent((smu), (speed)) : 0) + + #define smu_msg_get_index(smu, msg) \ + ((smu)->ppt_funcs? ((smu)->ppt_funcs->get_smu_msg_index? (smu)->ppt_funcs->get_smu_msg_index((smu), (msg)) : -EINVAL) : -EINVAL) +diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +index aee8d27a5473..2eb5ad813ec8 100644 +--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c ++++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +@@ -1748,6 +1748,92 @@ static int smu_v11_0_get_current_rpm(struct smu_context *smu, + return 0; + } + ++static uint32_t ++smu_v11_0_get_fan_control_mode(struct smu_context *smu) ++{ ++ if (!smu_feature_is_enabled(smu, FEATURE_FAN_CONTROL_BIT)) ++ return AMD_FAN_CTRL_MANUAL; ++ else ++ return AMD_FAN_CTRL_AUTO; ++} ++ ++static int ++smu_v11_0_get_fan_speed_percent(struct smu_context *smu, ++ uint32_t *speed) ++{ ++ int ret = 0; ++ uint32_t percent = 0; ++ uint32_t current_rpm; ++ PPTable_t *pptable = smu->smu_table.driver_pptable; ++ ++ ret = smu_v11_0_get_current_rpm(smu, ¤t_rpm); ++ percent = current_rpm * 100 / pptable->FanMaximumRpm; ++ *speed = percent > 100 ? 100 : percent; ++ ++ return ret; ++} ++ ++static int ++smu_v11_0_smc_fan_control(struct smu_context *smu, bool start) ++{ ++ int ret = 0; ++ ++ if (smu_feature_is_supported(smu, FEATURE_FAN_CONTROL_BIT)) ++ return 0; ++ ++ ret = smu_feature_set_enabled(smu, FEATURE_FAN_CONTROL_BIT, start); ++ if (ret) ++ pr_err("[%s]%s smc FAN CONTROL feature failed!", ++ __func__, (start ? "Start" : "Stop")); ++ ++ return ret; ++} ++ ++static int ++smu_v11_0_set_fan_static_mode(struct smu_context *smu, uint32_t mode) ++{ ++ struct amdgpu_device *adev = smu->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 ++smu_v11_0_set_fan_speed_percent(struct smu_context *smu, uint32_t speed) ++{ ++ struct amdgpu_device *adev = smu->adev; ++ uint32_t duty100; ++ uint32_t duty; ++ uint64_t tmp64; ++ bool stop = 0; ++ ++ if (speed > 100) ++ speed = 100; ++ ++ if (smu_v11_0_smc_fan_control(smu, stop)) ++ return -EINVAL; ++ duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1), ++ CG_FDO_CTRL1, FMAX_DUTY100); ++ if (!duty100) ++ 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 smu_v11_0_set_fan_static_mode(smu, FDO_PWM_MODE_STATIC); ++} ++ + static const struct smu_funcs smu_v11_0_funcs = { + .init_microcode = smu_v11_0_init_microcode, + .load_microcode = smu_v11_0_load_microcode, +@@ -1799,6 +1885,9 @@ static const struct smu_funcs smu_v11_0_funcs = { + .dpm_set_uvd_enable = smu_v11_0_dpm_set_uvd_enable, + .dpm_set_vce_enable = smu_v11_0_dpm_set_vce_enable, + .get_current_rpm = smu_v11_0_get_current_rpm, ++ .get_fan_control_mode = smu_v11_0_get_fan_control_mode, ++ .get_fan_speed_percent = smu_v11_0_get_fan_speed_percent, ++ .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent, + }; + + void smu_v11_0_set_smu_funcs(struct smu_context *smu) +-- +2.17.1 + |