LCOV - code coverage report
Current view: top level - drivers/gpu/drm/amd/pm/powerplay/hwmgr - vega20_thermal.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 124 0.0 %
Date: 2022-12-09 01:23:36 Functions: 0 17 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2018 Advanced Micro Devices, Inc.
       3             :  *
       4             :  * Permission is hereby granted, free of charge, to any person obtaining a
       5             :  * copy of this software and associated documentation files (the "Software"),
       6             :  * to deal in the Software without restriction, including without limitation
       7             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       8             :  * and/or sell copies of the Software, and to permit persons to whom the
       9             :  * Software is furnished to do so, subject to the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice shall be included in
      12             :  * all copies or substantial portions of the Software.
      13             :  *
      14             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      15             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      16             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      17             :  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
      18             :  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      19             :  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
      20             :  * OTHER DEALINGS IN THE SOFTWARE.
      21             :  *
      22             :  */
      23             : 
      24             : #include "vega20_thermal.h"
      25             : #include "vega20_hwmgr.h"
      26             : #include "vega20_smumgr.h"
      27             : #include "vega20_ppsmc.h"
      28             : #include "vega20_inc.h"
      29             : #include "soc15_common.h"
      30             : #include "pp_debug.h"
      31             : 
      32           0 : static int vega20_disable_fan_control_feature(struct pp_hwmgr *hwmgr)
      33             : {
      34           0 :         struct vega20_hwmgr *data = hwmgr->backend;
      35           0 :         int ret = 0;
      36             : 
      37           0 :         if (data->smu_features[GNLD_FAN_CONTROL].supported) {
      38           0 :                 ret = vega20_enable_smc_features(
      39             :                                 hwmgr, false,
      40             :                                 data->smu_features[GNLD_FAN_CONTROL].
      41             :                                 smu_feature_bitmap);
      42           0 :                 PP_ASSERT_WITH_CODE(!ret,
      43             :                                 "Disable FAN CONTROL feature Failed!",
      44             :                                 return ret);
      45           0 :                 data->smu_features[GNLD_FAN_CONTROL].enabled = false;
      46             :         }
      47             : 
      48             :         return ret;
      49             : }
      50             : 
      51           0 : int vega20_fan_ctrl_stop_smc_fan_control(struct pp_hwmgr *hwmgr)
      52             : {
      53           0 :         struct vega20_hwmgr *data = hwmgr->backend;
      54             : 
      55           0 :         if (data->smu_features[GNLD_FAN_CONTROL].supported)
      56           0 :                 return vega20_disable_fan_control_feature(hwmgr);
      57             : 
      58             :         return 0;
      59             : }
      60             : 
      61           0 : static int vega20_enable_fan_control_feature(struct pp_hwmgr *hwmgr)
      62             : {
      63           0 :         struct vega20_hwmgr *data = hwmgr->backend;
      64           0 :         int ret = 0;
      65             : 
      66           0 :         if (data->smu_features[GNLD_FAN_CONTROL].supported) {
      67           0 :                 ret = vega20_enable_smc_features(
      68             :                                 hwmgr, true,
      69             :                                 data->smu_features[GNLD_FAN_CONTROL].
      70             :                                 smu_feature_bitmap);
      71           0 :                 PP_ASSERT_WITH_CODE(!ret,
      72             :                                 "Enable FAN CONTROL feature Failed!",
      73             :                                 return ret);
      74           0 :                 data->smu_features[GNLD_FAN_CONTROL].enabled = true;
      75             :         }
      76             : 
      77             :         return ret;
      78             : }
      79             : 
      80           0 : int vega20_fan_ctrl_start_smc_fan_control(struct pp_hwmgr *hwmgr)
      81             : {
      82           0 :         struct vega20_hwmgr *data = hwmgr->backend;
      83             : 
      84           0 :         if (data->smu_features[GNLD_FAN_CONTROL].supported)
      85           0 :                 return vega20_enable_fan_control_feature(hwmgr);
      86             : 
      87             :         return 0;
      88             : }
      89             : 
      90           0 : static int vega20_fan_ctrl_set_static_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
      91             : {
      92           0 :         struct amdgpu_device *adev = hwmgr->adev;
      93             : 
      94           0 :         WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2,
      95             :                         REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
      96             :                                 CG_FDO_CTRL2, TMIN, 0));
      97           0 :         WREG32_SOC15(THM, 0, mmCG_FDO_CTRL2,
      98             :                         REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL2),
      99             :                                 CG_FDO_CTRL2, FDO_PWM_MODE, mode));
     100             : 
     101           0 :         return 0;
     102             : }
     103             : 
     104           0 : static int vega20_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm)
     105             : {
     106           0 :         int ret = 0;
     107             : 
     108           0 :         PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc(hwmgr,
     109             :                                 PPSMC_MSG_GetCurrentRpm,
     110             :                                 current_rpm)) == 0,
     111             :                         "Attempt to get current RPM from SMC Failed!",
     112             :                         return ret);
     113             : 
     114             :         return 0;
     115             : }
     116             : 
     117           0 : int vega20_fan_ctrl_get_fan_speed_pwm(struct pp_hwmgr *hwmgr,
     118             :                 uint32_t *speed)
     119             : {
     120           0 :         struct amdgpu_device *adev = hwmgr->adev;
     121             :         uint32_t duty100, duty;
     122             :         uint64_t tmp64;
     123             : 
     124           0 :         duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1),
     125             :                                 CG_FDO_CTRL1, FMAX_DUTY100);
     126           0 :         duty = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_THERMAL_STATUS),
     127             :                                 CG_THERMAL_STATUS, FDO_PWM_DUTY);
     128             : 
     129           0 :         if (!duty100)
     130             :                 return -EINVAL;
     131             : 
     132           0 :         tmp64 = (uint64_t)duty * 255;
     133           0 :         do_div(tmp64, duty100);
     134           0 :         *speed = MIN((uint32_t)tmp64, 255);
     135             : 
     136           0 :         return 0;
     137             : }
     138             : 
     139           0 : int vega20_fan_ctrl_set_fan_speed_pwm(struct pp_hwmgr *hwmgr,
     140             :                 uint32_t speed)
     141             : {
     142           0 :         struct amdgpu_device *adev = hwmgr->adev;
     143             :         uint32_t duty100;
     144             :         uint32_t duty;
     145             :         uint64_t tmp64;
     146             : 
     147           0 :         speed = MIN(speed, 255);
     148             : 
     149           0 :         if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))
     150             :                 vega20_fan_ctrl_stop_smc_fan_control(hwmgr);
     151             : 
     152           0 :         duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1),
     153             :                                     CG_FDO_CTRL1, FMAX_DUTY100);
     154             : 
     155           0 :         if (duty100 == 0)
     156             :                 return -EINVAL;
     157             : 
     158           0 :         tmp64 = (uint64_t)speed * duty100;
     159           0 :         do_div(tmp64, 255);
     160           0 :         duty = (uint32_t)tmp64;
     161             : 
     162           0 :         WREG32_SOC15(THM, 0, mmCG_FDO_CTRL0,
     163             :                 REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL0),
     164             :                         CG_FDO_CTRL0, FDO_STATIC_DUTY, duty));
     165             : 
     166           0 :         return vega20_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
     167             : }
     168             : 
     169           0 : int vega20_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr,
     170             :                 struct phm_fan_speed_info *fan_speed_info)
     171             : {
     172           0 :         memset(fan_speed_info, 0, sizeof(*fan_speed_info));
     173           0 :         fan_speed_info->supports_percent_read = true;
     174           0 :         fan_speed_info->supports_percent_write = true;
     175           0 :         fan_speed_info->supports_rpm_read = true;
     176           0 :         fan_speed_info->supports_rpm_write = true;
     177             : 
     178           0 :         return 0;
     179             : }
     180             : 
     181           0 : int vega20_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
     182             : {
     183           0 :         *speed = 0;
     184             : 
     185           0 :         return vega20_get_current_rpm(hwmgr, speed);
     186             : }
     187             : 
     188           0 : int vega20_fan_ctrl_set_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t speed)
     189             : {
     190           0 :         struct amdgpu_device *adev = hwmgr->adev;
     191             :         uint32_t tach_period, crystal_clock_freq;
     192           0 :         int result = 0;
     193             : 
     194           0 :         if (!speed)
     195             :                 return -EINVAL;
     196             : 
     197           0 :         if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl)) {
     198           0 :                 result = vega20_fan_ctrl_stop_smc_fan_control(hwmgr);
     199           0 :                 if (result)
     200             :                         return result;
     201             :         }
     202             : 
     203           0 :         crystal_clock_freq = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);
     204           0 :         tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed);
     205           0 :         WREG32_SOC15(THM, 0, mmCG_TACH_CTRL,
     206             :                         REG_SET_FIELD(RREG32_SOC15(THM, 0, mmCG_TACH_CTRL),
     207             :                                 CG_TACH_CTRL, TARGET_PERIOD,
     208             :                                 tach_period));
     209             : 
     210           0 :         return vega20_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC_RPM);
     211             : }
     212             : 
     213             : /**
     214             :  * vega20_thermal_get_temperature - Reads the remote temperature from the SIslands thermal controller.
     215             :  *
     216             :  * @hwmgr: The address of the hardware manager.
     217             :  */
     218           0 : int vega20_thermal_get_temperature(struct pp_hwmgr *hwmgr)
     219             : {
     220           0 :         struct amdgpu_device *adev = hwmgr->adev;
     221           0 :         int temp = 0;
     222             : 
     223           0 :         temp = RREG32_SOC15(THM, 0, mmCG_MULT_THERMAL_STATUS);
     224             : 
     225           0 :         temp = (temp & CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK) >>
     226             :                         CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT;
     227             : 
     228           0 :         temp = temp & 0x1ff;
     229             : 
     230           0 :         temp *= PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
     231           0 :         return temp;
     232             : }
     233             : 
     234             : /**
     235             :  * vega20_thermal_set_temperature_range - Set the requested temperature range for high and low alert signals
     236             :  *
     237             :  * @hwmgr: The address of the hardware manager.
     238             :  * @range: Temperature range to be programmed for high and low alert signals
     239             :  * Exception: PP_Result_BadInput if the input data is not valid.
     240             :  */
     241           0 : static int vega20_thermal_set_temperature_range(struct pp_hwmgr *hwmgr,
     242             :                 struct PP_TemperatureRange *range)
     243             : {
     244           0 :         struct phm_ppt_v3_information *pptable_information =
     245             :                 (struct phm_ppt_v3_information *)hwmgr->pptable;
     246           0 :         struct amdgpu_device *adev = hwmgr->adev;
     247           0 :         int low = VEGA20_THERMAL_MINIMUM_ALERT_TEMP;
     248           0 :         int high = VEGA20_THERMAL_MAXIMUM_ALERT_TEMP;
     249             :         uint32_t val;
     250             : 
     251             :         /* compare them in unit celsius degree */
     252           0 :         if (low < range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)
     253           0 :                 low = range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
     254           0 :         if (high > pptable_information->us_software_shutdown_temp)
     255           0 :                 high = pptable_information->us_software_shutdown_temp;
     256             : 
     257           0 :         if (low > high)
     258             :                 return -EINVAL;
     259             : 
     260           0 :         val = RREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL);
     261             : 
     262           0 :         val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5);
     263           0 :         val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1);
     264           0 :         val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, high);
     265           0 :         val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, low);
     266           0 :         val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK);
     267             : 
     268           0 :         WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val);
     269             : 
     270             :         return 0;
     271             : }
     272             : 
     273             : /**
     274             :  * vega20_thermal_enable_alert - Enable thermal alerts on the RV770 thermal controller.
     275             :  *
     276             :  * @hwmgr: The address of the hardware manager.
     277             :  */
     278           0 : static int vega20_thermal_enable_alert(struct pp_hwmgr *hwmgr)
     279             : {
     280           0 :         struct amdgpu_device *adev = hwmgr->adev;
     281           0 :         uint32_t val = 0;
     282             : 
     283           0 :         val |= (1 << THM_THERMAL_INT_ENA__THERM_INTH_CLR__SHIFT);
     284           0 :         val |= (1 << THM_THERMAL_INT_ENA__THERM_INTL_CLR__SHIFT);
     285           0 :         val |= (1 << THM_THERMAL_INT_ENA__THERM_TRIGGER_CLR__SHIFT);
     286             : 
     287           0 :         WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_ENA, val);
     288             : 
     289           0 :         return 0;
     290             : }
     291             : 
     292             : /**
     293             :  * vega20_thermal_disable_alert - Disable thermal alerts on the RV770 thermal controller.
     294             :  * @hwmgr: The address of the hardware manager.
     295             :  */
     296           0 : int vega20_thermal_disable_alert(struct pp_hwmgr *hwmgr)
     297             : {
     298           0 :         struct amdgpu_device *adev = hwmgr->adev;
     299             : 
     300           0 :         WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_ENA, 0);
     301             : 
     302           0 :         return 0;
     303             : }
     304             : 
     305             : /**
     306             :  * vega20_thermal_stop_thermal_controller - Uninitialize the thermal controller.
     307             :  * Currently just disables alerts.
     308             :  * @hwmgr: The address of the hardware manager.
     309             :  */
     310           0 : int vega20_thermal_stop_thermal_controller(struct pp_hwmgr *hwmgr)
     311             : {
     312           0 :         int result = vega20_thermal_disable_alert(hwmgr);
     313             : 
     314           0 :         return result;
     315             : }
     316             : 
     317             : /**
     318             :  * vega20_thermal_setup_fan_table - Set up the fan table to control the fan using the SMC.
     319             :  * @hwmgr:  the address of the powerplay hardware manager.
     320             :  */
     321             : static int vega20_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
     322             : {
     323             :         int ret;
     324           0 :         struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend);
     325           0 :         PPTable_t *table = &(data->smc_state_table.pp_table);
     326             : 
     327           0 :         ret = smum_send_msg_to_smc_with_parameter(hwmgr,
     328             :                                 PPSMC_MSG_SetFanTemperatureTarget,
     329           0 :                                 (uint32_t)table->FanTargetTemperature,
     330             :                                 NULL);
     331             : 
     332             :         return ret;
     333             : }
     334             : 
     335           0 : int vega20_start_thermal_controller(struct pp_hwmgr *hwmgr,
     336             :                                 struct PP_TemperatureRange *range)
     337             : {
     338           0 :         int ret = 0;
     339             : 
     340           0 :         if (range == NULL)
     341             :                 return -EINVAL;
     342             : 
     343           0 :         ret = vega20_thermal_set_temperature_range(hwmgr, range);
     344           0 :         if (ret)
     345             :                 return ret;
     346             : 
     347           0 :         ret = vega20_thermal_enable_alert(hwmgr);
     348           0 :         if (ret)
     349             :                 return ret;
     350             : 
     351           0 :         ret = vega20_thermal_setup_fan_table(hwmgr);
     352             : 
     353           0 :         return ret;
     354             : };

Generated by: LCOV version 1.14