drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c
Extension
.c
Size
19845 bytes
Lines
658
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

#include "vega10_thermal.h"
#include "vega10_hwmgr.h"
#include "vega10_smumgr.h"
#include "vega10_ppsmc.h"
#include "vega10_inc.h"
#include "soc15_common.h"
#include "pp_debug.h"

static int vega10_get_current_rpm(struct pp_hwmgr *hwmgr, uint32_t *current_rpm)
{
	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentRpm, current_rpm);
	return 0;
}

int vega10_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr,
		struct phm_fan_speed_info *fan_speed_info)
{

	if (hwmgr->thermal_controller.fanInfo.bNoFan)
		return 0;

	fan_speed_info->supports_percent_read = true;
	fan_speed_info->supports_percent_write = true;
	fan_speed_info->min_percent = 0;
	fan_speed_info->max_percent = 100;

	if (PP_CAP(PHM_PlatformCaps_FanSpeedInTableIsRPM) &&
		hwmgr->thermal_controller.fanInfo.
		ucTachometerPulsesPerRevolution) {
		fan_speed_info->supports_rpm_read = true;
		fan_speed_info->supports_rpm_write = true;
		fan_speed_info->min_rpm =
				hwmgr->thermal_controller.fanInfo.ulMinRPM;
		fan_speed_info->max_rpm =
				hwmgr->thermal_controller.fanInfo.ulMaxRPM;
	} else {
		fan_speed_info->min_rpm = 0;
		fan_speed_info->max_rpm = 0;
	}

	return 0;
}

int vega10_fan_ctrl_get_fan_speed_pwm(struct pp_hwmgr *hwmgr,
		uint32_t *speed)
{
	struct amdgpu_device *adev = hwmgr->adev;
	uint32_t duty100, duty;
	uint64_t tmp64;

	duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1),
				CG_FDO_CTRL1, FMAX_DUTY100);
	duty = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_THERMAL_STATUS),
				CG_THERMAL_STATUS, FDO_PWM_DUTY);

	if (!duty100)
		return -EINVAL;

	tmp64 = (uint64_t)duty * 255;
	do_div(tmp64, duty100);
	*speed = min_t(uint32_t, tmp64, 255);

	return 0;
}

int vega10_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed)
{
	struct amdgpu_device *adev = hwmgr->adev;
	struct vega10_hwmgr *data = hwmgr->backend;
	uint32_t tach_period;
	uint32_t crystal_clock_freq;
	int result = 0;

	if (hwmgr->thermal_controller.fanInfo.bNoFan)
		return -1;

	if (data->smu_features[GNLD_FAN_CONTROL].supported) {
		result = vega10_get_current_rpm(hwmgr, speed);
	} else {
		tach_period =
			REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_TACH_STATUS),
					  CG_TACH_STATUS,
					  TACH_PERIOD);

		if (tach_period == 0)
			return -EINVAL;

		crystal_clock_freq = amdgpu_asic_get_xclk((struct amdgpu_device *)hwmgr->adev);

		*speed = 60 * crystal_clock_freq * 10000 / tach_period;

Annotation

Implementation Notes