Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e03cea36 authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/radeon/dpm: add smc fan control for CI (v2)

Enable smc fan control for CI boards.  Should
reduce the fan noise on systems with a higher
default fan profile.

v2: disable by default, add additional fan setup, rpm control

bug:
https://bugs.freedesktop.org/show_bug.cgi?id=73338



Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 39471ad3
Loading
Loading
Loading
Loading
+344 −1
Original line number Original line Diff line number Diff line
@@ -184,6 +184,9 @@ static int ci_set_overdrive_target_tdp(struct radeon_device *rdev,
				       u32 target_tdp);
				       u32 target_tdp);
static int ci_update_uvd_dpm(struct radeon_device *rdev, bool gate);
static int ci_update_uvd_dpm(struct radeon_device *rdev, bool gate);


static PPSMC_Result ci_send_msg_to_smc_with_parameter(struct radeon_device *rdev,
						      PPSMC_Msg msg, u32 parameter);

static struct ci_power_info *ci_get_pi(struct radeon_device *rdev)
static struct ci_power_info *ci_get_pi(struct radeon_device *rdev)
{
{
        struct ci_power_info *pi = rdev->pm.dpm.priv;
        struct ci_power_info *pi = rdev->pm.dpm.priv;
@@ -355,6 +358,21 @@ static int ci_populate_dw8(struct radeon_device *rdev)
	return 0;
	return 0;
}
}


static int ci_populate_fuzzy_fan(struct radeon_device *rdev)
{
	struct ci_power_info *pi = ci_get_pi(rdev);

	if ((rdev->pm.dpm.fan.fan_output_sensitivity & (1 << 15)) ||
	    (rdev->pm.dpm.fan.fan_output_sensitivity == 0))
		rdev->pm.dpm.fan.fan_output_sensitivity =
			rdev->pm.dpm.fan.default_fan_output_sensitivity;

	pi->smc_powertune_table.FuzzyFan_PwmSetDelta =
		cpu_to_be16(rdev->pm.dpm.fan.fan_output_sensitivity);

	return 0;
}

static int ci_min_max_v_gnbl_pm_lid_from_bapm_vddc(struct radeon_device *rdev)
static int ci_min_max_v_gnbl_pm_lid_from_bapm_vddc(struct radeon_device *rdev)
{
{
	struct ci_power_info *pi = ci_get_pi(rdev);
	struct ci_power_info *pi = ci_get_pi(rdev);
@@ -478,6 +496,9 @@ static int ci_populate_pm_base(struct radeon_device *rdev)
		if (ret)
		if (ret)
			return ret;
			return ret;
		ret = ci_populate_dw8(rdev);
		ret = ci_populate_dw8(rdev);
		if (ret)
			return ret;
		ret = ci_populate_fuzzy_fan(rdev);
		if (ret)
		if (ret)
			return ret;
			return ret;
		ret = ci_min_max_v_gnbl_pm_lid_from_bapm_vddc(rdev);
		ret = ci_min_max_v_gnbl_pm_lid_from_bapm_vddc(rdev);
@@ -859,6 +880,7 @@ static int ci_thermal_enable_alert(struct radeon_device *rdev,


	if (enable) {
	if (enable) {
		thermal_int &= ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
		thermal_int &= ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
		WREG32_SMC(CG_THERMAL_INT, thermal_int);
		rdev->irq.dpm_thermal = false;
		rdev->irq.dpm_thermal = false;
		result = ci_send_msg_to_smc(rdev, PPSMC_MSG_Thermal_Cntl_Enable);
		result = ci_send_msg_to_smc(rdev, PPSMC_MSG_Thermal_Cntl_Enable);
		if (result != PPSMC_Result_OK) {
		if (result != PPSMC_Result_OK) {
@@ -867,6 +889,7 @@ static int ci_thermal_enable_alert(struct radeon_device *rdev,
		}
		}
	} else {
	} else {
		thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
		thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
		WREG32_SMC(CG_THERMAL_INT, thermal_int);
		rdev->irq.dpm_thermal = true;
		rdev->irq.dpm_thermal = true;
		result = ci_send_msg_to_smc(rdev, PPSMC_MSG_Thermal_Cntl_Disable);
		result = ci_send_msg_to_smc(rdev, PPSMC_MSG_Thermal_Cntl_Disable);
		if (result != PPSMC_Result_OK) {
		if (result != PPSMC_Result_OK) {
@@ -875,10 +898,323 @@ static int ci_thermal_enable_alert(struct radeon_device *rdev,
		}
		}
	}
	}


	WREG32_SMC(CG_THERMAL_INT, thermal_int);
	return 0;
}

static void ci_fan_ctrl_set_static_mode(struct radeon_device *rdev, u32 mode)
{
	struct ci_power_info *pi = ci_get_pi(rdev);
	u32 tmp;

	if (pi->fan_ctrl_is_in_default_mode) {
		tmp = (RREG32_SMC(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK) >> FDO_PWM_MODE_SHIFT;
		pi->fan_ctrl_default_mode = tmp;
		tmp = (RREG32_SMC(CG_FDO_CTRL2) & TMIN_MASK) >> TMIN_SHIFT;
		pi->t_min = tmp;
		pi->fan_ctrl_is_in_default_mode = false;
	}

	tmp = RREG32_SMC(CG_FDO_CTRL2) & ~TMIN_MASK;
	tmp |= TMIN(0);
	WREG32_SMC(CG_FDO_CTRL2, tmp);

	tmp = RREG32_SMC(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK;
	tmp |= FDO_PWM_MODE(mode);
	WREG32_SMC(CG_FDO_CTRL2, tmp);
}

static int ci_thermal_setup_fan_table(struct radeon_device *rdev)
{
	struct ci_power_info *pi = ci_get_pi(rdev);
	SMU7_Discrete_FanTable fan_table = { FDO_MODE_HARDWARE };
	u32 duty100;
	u32 t_diff1, t_diff2, pwm_diff1, pwm_diff2;
	u16 fdo_min, slope1, slope2;
	u32 reference_clock, tmp;
	int ret;
	u64 tmp64;

	if (!pi->fan_table_start) {
		rdev->pm.dpm.fan.ucode_fan_control = false;
		return 0;
	}

	duty100 = (RREG32_SMC(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT;

	if (duty100 == 0) {
		rdev->pm.dpm.fan.ucode_fan_control = false;
		return 0;
	}

	tmp64 = (u64)rdev->pm.dpm.fan.pwm_min * duty100;
	do_div(tmp64, 10000);
	fdo_min = (u16)tmp64;

	t_diff1 = rdev->pm.dpm.fan.t_med - rdev->pm.dpm.fan.t_min;
	t_diff2 = rdev->pm.dpm.fan.t_high - rdev->pm.dpm.fan.t_med;

	pwm_diff1 = rdev->pm.dpm.fan.pwm_med - rdev->pm.dpm.fan.pwm_min;
	pwm_diff2 = rdev->pm.dpm.fan.pwm_high - rdev->pm.dpm.fan.pwm_med;

	slope1 = (u16)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100);
	slope2 = (u16)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100);

	fan_table.TempMin = cpu_to_be16((50 + rdev->pm.dpm.fan.t_min) / 100);
	fan_table.TempMed = cpu_to_be16((50 + rdev->pm.dpm.fan.t_med) / 100);
	fan_table.TempMax = cpu_to_be16((50 + rdev->pm.dpm.fan.t_max) / 100);

	fan_table.Slope1 = cpu_to_be16(slope1);
	fan_table.Slope2 = cpu_to_be16(slope2);

	fan_table.FdoMin = cpu_to_be16(fdo_min);

	fan_table.HystDown = cpu_to_be16(rdev->pm.dpm.fan.t_hyst);

	fan_table.HystUp = cpu_to_be16(1);

	fan_table.HystSlope = cpu_to_be16(1);

	fan_table.TempRespLim = cpu_to_be16(5);

	reference_clock = radeon_get_xclk(rdev);

	fan_table.RefreshPeriod = cpu_to_be32((rdev->pm.dpm.fan.cycle_delay *
					       reference_clock) / 1600);

	fan_table.FdoMax = cpu_to_be16((u16)duty100);

	tmp = (RREG32_SMC(CG_MULT_THERMAL_CTRL) & TEMP_SEL_MASK) >> TEMP_SEL_SHIFT;
	fan_table.TempSrc = (uint8_t)tmp;

	ret = ci_copy_bytes_to_smc(rdev,
				   pi->fan_table_start,
				   (u8 *)(&fan_table),
				   sizeof(fan_table),
				   pi->sram_end);

	if (ret) {
		DRM_ERROR("Failed to load fan table to the SMC.");
		rdev->pm.dpm.fan.ucode_fan_control = false;
	}

	return 0;
}

static int ci_fan_ctrl_start_smc_fan_control(struct radeon_device *rdev)
{
	struct ci_power_info *pi = ci_get_pi(rdev);
	PPSMC_Result ret;

	if (pi->caps_od_fuzzy_fan_control_support) {
		ret = ci_send_msg_to_smc_with_parameter(rdev,
							PPSMC_StartFanControl,
							FAN_CONTROL_FUZZY);
		if (ret != PPSMC_Result_OK)
			return -EINVAL;
		ret = ci_send_msg_to_smc_with_parameter(rdev,
							PPSMC_MSG_SetFanPwmMax,
							rdev->pm.dpm.fan.default_max_fan_pwm);
		if (ret != PPSMC_Result_OK)
			return -EINVAL;
	} else {
		ret = ci_send_msg_to_smc_with_parameter(rdev,
							PPSMC_StartFanControl,
							FAN_CONTROL_TABLE);
		if (ret != PPSMC_Result_OK)
			return -EINVAL;
	}

	return 0;
}

#if 0
static int ci_fan_ctrl_stop_smc_fan_control(struct radeon_device *rdev)
{
	PPSMC_Result ret;

	ret = ci_send_msg_to_smc(rdev, PPSMC_StopFanControl);
	if (ret == PPSMC_Result_OK)
		return 0;
	else
		return -EINVAL;
}

static int ci_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev,
					     u32 *speed)
{
	u32 duty, duty100;
	u64 tmp64;

	if (rdev->pm.no_fan)
		return -ENOENT;

	duty100 = (RREG32_SMC(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT;
	duty = (RREG32_SMC(CG_THERMAL_STATUS) & FDO_PWM_DUTY_MASK) >> FDO_PWM_DUTY_SHIFT;

	if (duty100 == 0)
		return -EINVAL;

	tmp64 = (u64)duty * 100;
	do_div(tmp64, duty100);
	*speed = (u32)tmp64;

	if (*speed > 100)
		*speed = 100;

	return 0;
}

static int ci_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev,
					     u32 speed)
{
	u32 tmp;
	u32 duty, duty100;
	u64 tmp64;

	if (rdev->pm.no_fan)
		return -ENOENT;

	if (speed > 100)
		return -EINVAL;

	if (rdev->pm.dpm.fan.ucode_fan_control)
		ci_fan_ctrl_stop_smc_fan_control(rdev);

	duty100 = (RREG32_SMC(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT;

	if (duty100 == 0)
		return -EINVAL;

	tmp64 = (u64)speed * duty100;
	do_div(tmp64, 100);
	duty = (u32)tmp64;

	tmp = RREG32_SMC(CG_FDO_CTRL0) & ~FDO_STATIC_DUTY_MASK;
	tmp |= FDO_STATIC_DUTY(duty);
	WREG32_SMC(CG_FDO_CTRL0, tmp);

	ci_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC);

	return 0;
}

static int ci_fan_ctrl_get_fan_speed_rpm(struct radeon_device *rdev,
					 u32 *speed)
{
	u32 tach_period;
	u32 xclk = radeon_get_xclk(rdev);

	if (rdev->pm.no_fan)
		return -ENOENT;

	if (rdev->pm.fan_pulses_per_revolution == 0)
		return -ENOENT;

	tach_period = (RREG32_SMC(CG_TACH_STATUS) & TACH_PERIOD_MASK) >> TACH_PERIOD_SHIFT;
	if (tach_period == 0)
		return -ENOENT;

	*speed = 60 * xclk * 10000 / tach_period;

	return 0;
}

static int ci_fan_ctrl_set_fan_speed_rpm(struct radeon_device *rdev,
					 u32 speed)
{
	u32 tach_period, tmp;
	u32 xclk = radeon_get_xclk(rdev);

	if (rdev->pm.no_fan)
		return -ENOENT;

	if (rdev->pm.fan_pulses_per_revolution == 0)
		return -ENOENT;

	if ((speed < rdev->pm.fan_min_rpm) ||
	    (speed > rdev->pm.fan_max_rpm))
		return -EINVAL;

	if (rdev->pm.dpm.fan.ucode_fan_control)
		ci_fan_ctrl_stop_smc_fan_control(rdev);

	tach_period = 60 * xclk * 10000 / (8 * speed);
	tmp = RREG32_SMC(CG_TACH_CTRL) & ~TARGET_PERIOD_MASK;
	tmp |= TARGET_PERIOD(tach_period);
	WREG32_SMC(CG_TACH_CTRL, tmp);

	ci_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC);


	return 0;
	return 0;
}
}
#endif

static void ci_fan_ctrl_set_default_mode(struct radeon_device *rdev)
{
	struct ci_power_info *pi = ci_get_pi(rdev);
	u32 tmp;

	if (!pi->fan_ctrl_is_in_default_mode) {
		tmp = RREG32_SMC(CG_FDO_CTRL2) & ~FDO_PWM_MODE_MASK;
		tmp |= FDO_PWM_MODE(pi->fan_ctrl_default_mode);
		WREG32_SMC(CG_FDO_CTRL2, tmp);

		tmp = RREG32_SMC(CG_FDO_CTRL2) & TMIN_MASK;
		tmp |= TMIN(pi->t_min);
		WREG32_SMC(CG_FDO_CTRL2, tmp);
		pi->fan_ctrl_is_in_default_mode = true;
	}
}

static void ci_thermal_start_smc_fan_control(struct radeon_device *rdev)
{
	if (rdev->pm.dpm.fan.ucode_fan_control) {
		ci_fan_ctrl_start_smc_fan_control(rdev);
		ci_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC);
	}
}

static void ci_thermal_initialize(struct radeon_device *rdev)
{
	u32 tmp;

	if (rdev->pm.fan_pulses_per_revolution) {
		tmp = RREG32_SMC(CG_TACH_CTRL) & ~EDGE_PER_REV_MASK;
		tmp |= EDGE_PER_REV(rdev->pm.fan_pulses_per_revolution -1);
		WREG32_SMC(CG_TACH_CTRL, tmp);
	}

	tmp = RREG32_SMC(CG_FDO_CTRL2) & ~TACH_PWM_RESP_RATE_MASK;
	tmp |= TACH_PWM_RESP_RATE(0x28);
	WREG32_SMC(CG_FDO_CTRL2, tmp);
}

static int ci_thermal_start_thermal_controller(struct radeon_device *rdev)
{
	int ret;

	ci_thermal_initialize(rdev);
	ret = ci_thermal_set_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
	if (ret)
		return ret;
	ret = ci_thermal_enable_alert(rdev, true);
	if (ret)
		return ret;
	if (rdev->pm.dpm.fan.ucode_fan_control) {
		ret = ci_thermal_setup_fan_table(rdev);
		if (ret)
			return ret;
		ci_thermal_start_smc_fan_control(rdev);
	}

	return 0;
}

static void ci_thermal_stop_thermal_controller(struct radeon_device *rdev)
{
	if (!rdev->pm.no_fan)
		ci_fan_ctrl_set_default_mode(rdev);
}


#if 0
#if 0
static int ci_read_smc_soft_register(struct radeon_device *rdev,
static int ci_read_smc_soft_register(struct radeon_device *rdev,
@@ -4841,6 +5177,8 @@ int ci_dpm_enable(struct radeon_device *rdev)


	ci_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
	ci_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);


	ci_thermal_start_thermal_controller(rdev);

	ci_update_current_ps(rdev, boot_ps);
	ci_update_current_ps(rdev, boot_ps);


	return 0;
	return 0;
@@ -4886,6 +5224,8 @@ void ci_dpm_disable(struct radeon_device *rdev)
	if (!ci_is_smc_running(rdev))
	if (!ci_is_smc_running(rdev))
		return;
		return;


	ci_thermal_stop_thermal_controller(rdev);

	if (pi->thermal_protection)
	if (pi->thermal_protection)
		ci_enable_thermal_protection(rdev, false);
		ci_enable_thermal_protection(rdev, false);
	ci_enable_power_containment(rdev, false);
	ci_enable_power_containment(rdev, false);
@@ -5473,6 +5813,9 @@ int ci_dpm_init(struct radeon_device *rdev)
		rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc =
		rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc =
			rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
			rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;


	pi->fan_ctrl_is_in_default_mode = true;
	rdev->pm.dpm.fan.ucode_fan_control = false;

	return 0;
	return 0;
}
}


+5 −0
Original line number Original line Diff line number Diff line
@@ -266,6 +266,7 @@ struct ci_power_info {
	bool caps_automatic_dc_transition;
	bool caps_automatic_dc_transition;
	bool caps_sclk_throttle_low_notification;
	bool caps_sclk_throttle_low_notification;
	bool caps_dynamic_ac_timing;
	bool caps_dynamic_ac_timing;
	bool caps_od_fuzzy_fan_control_support;
	/* flags */
	/* flags */
	bool thermal_protection;
	bool thermal_protection;
	bool pcie_performance_request;
	bool pcie_performance_request;
@@ -287,6 +288,10 @@ struct ci_power_info {
	struct ci_ps current_ps;
	struct ci_ps current_ps;
	struct radeon_ps requested_rps;
	struct radeon_ps requested_rps;
	struct ci_ps requested_ps;
	struct ci_ps requested_ps;
	/* fan control */
	bool fan_ctrl_is_in_default_mode;
	u32 t_min;
	u32 fan_ctrl_default_mode;
};
};


#define CISLANDS_VOLTAGE_CONTROL_NONE                   0x0
#define CISLANDS_VOLTAGE_CONTROL_NONE                   0x0
+38 −2
Original line number Original line Diff line number Diff line
@@ -186,7 +186,10 @@
#define		DIG_THERM_DPM(x)			((x) << 14)
#define		DIG_THERM_DPM(x)			((x) << 14)
#define		DIG_THERM_DPM_MASK			0x003FC000
#define		DIG_THERM_DPM_MASK			0x003FC000
#define		DIG_THERM_DPM_SHIFT			14
#define		DIG_THERM_DPM_SHIFT			14

#define	CG_THERMAL_STATUS				0xC0300008
#define		FDO_PWM_DUTY(x)				((x) << 9)
#define		FDO_PWM_DUTY_MASK			(0xff << 9)
#define		FDO_PWM_DUTY_SHIFT			9
#define	CG_THERMAL_INT					0xC030000C
#define	CG_THERMAL_INT					0xC030000C
#define		CI_DIG_THERM_INTH(x)			((x) << 8)
#define		CI_DIG_THERM_INTH(x)			((x) << 8)
#define		CI_DIG_THERM_INTH_MASK			0x0000FF00
#define		CI_DIG_THERM_INTH_MASK			0x0000FF00
@@ -196,7 +199,10 @@
#define		CI_DIG_THERM_INTL_SHIFT			16
#define		CI_DIG_THERM_INTL_SHIFT			16
#define 	THERM_INT_MASK_HIGH			(1 << 24)
#define 	THERM_INT_MASK_HIGH			(1 << 24)
#define 	THERM_INT_MASK_LOW			(1 << 25)
#define 	THERM_INT_MASK_LOW			(1 << 25)

#define	CG_MULT_THERMAL_CTRL				0xC0300010
#define		TEMP_SEL(x)				((x) << 20)
#define		TEMP_SEL_MASK				(0xff << 20)
#define		TEMP_SEL_SHIFT				20
#define	CG_MULT_THERMAL_STATUS				0xC0300014
#define	CG_MULT_THERMAL_STATUS				0xC0300014
#define		ASIC_MAX_TEMP(x)			((x) << 0)
#define		ASIC_MAX_TEMP(x)			((x) << 0)
#define		ASIC_MAX_TEMP_MASK			0x000001ff
#define		ASIC_MAX_TEMP_MASK			0x000001ff
@@ -205,6 +211,36 @@
#define		CTF_TEMP_MASK				0x0003fe00
#define		CTF_TEMP_MASK				0x0003fe00
#define		CTF_TEMP_SHIFT				9
#define		CTF_TEMP_SHIFT				9


#define	CG_FDO_CTRL0					0xC0300064
#define		FDO_STATIC_DUTY(x)			((x) << 0)
#define		FDO_STATIC_DUTY_MASK			0x0000000F
#define		FDO_STATIC_DUTY_SHIFT			0
#define	CG_FDO_CTRL1					0xC0300068
#define		FMAX_DUTY100(x)				((x) << 0)
#define		FMAX_DUTY100_MASK			0x0000000F
#define		FMAX_DUTY100_SHIFT			0
#define	CG_FDO_CTRL2					0xC030006C
#define		TMIN(x)					((x) << 0)
#define		TMIN_MASK				0x0000000F
#define		TMIN_SHIFT				0
#define		FDO_PWM_MODE(x)				((x) << 11)
#define		FDO_PWM_MODE_MASK			(3 << 11)
#define		FDO_PWM_MODE_SHIFT			11
#define		TACH_PWM_RESP_RATE(x)			((x) << 25)
#define		TACH_PWM_RESP_RATE_MASK			(0x7f << 25)
#define		TACH_PWM_RESP_RATE_SHIFT		25
#define CG_TACH_CTRL                                    0xC0300070
#       define EDGE_PER_REV(x)                          ((x) << 0)
#       define EDGE_PER_REV_MASK                        (0x7 << 0)
#       define EDGE_PER_REV_SHIFT                       0
#       define TARGET_PERIOD(x)                         ((x) << 3)
#       define TARGET_PERIOD_MASK                       0xfffffff8
#       define TARGET_PERIOD_SHIFT                      3
#define CG_TACH_STATUS                                  0xC0300074
#       define TACH_PERIOD(x)                           ((x) << 0)
#       define TACH_PERIOD_MASK                         0xffffffff
#       define TACH_PERIOD_SHIFT                        0

#define CG_ECLK_CNTL                                    0xC05000AC
#define CG_ECLK_CNTL                                    0xC05000AC
#       define ECLK_DIVIDER_MASK                        0x7f
#       define ECLK_DIVIDER_MASK                        0x7f
#       define ECLK_DIR_CNTL_EN                         (1 << 8)
#       define ECLK_DIR_CNTL_EN                         (1 << 8)
+6 −0
Original line number Original line Diff line number Diff line
@@ -59,6 +59,11 @@
#define FDO_MODE_HARDWARE 0
#define FDO_MODE_HARDWARE 0
#define FDO_MODE_PIECE_WISE_LINEAR 1
#define FDO_MODE_PIECE_WISE_LINEAR 1


enum FAN_CONTROL {
	FAN_CONTROL_FUZZY,
	FAN_CONTROL_TABLE
};

#define PPSMC_Result_OK             ((uint8_t)0x01)
#define PPSMC_Result_OK             ((uint8_t)0x01)
#define PPSMC_Result_Failed         ((uint8_t)0xFF)
#define PPSMC_Result_Failed         ((uint8_t)0xFF)


@@ -155,6 +160,7 @@ typedef uint8_t PPSMC_Result;
#define PPSMC_MSG_MASTER_DeepSleep_ON         ((uint16_t) 0x18F)
#define PPSMC_MSG_MASTER_DeepSleep_ON         ((uint16_t) 0x18F)
#define PPSMC_MSG_MASTER_DeepSleep_OFF        ((uint16_t) 0x190)
#define PPSMC_MSG_MASTER_DeepSleep_OFF        ((uint16_t) 0x190)
#define PPSMC_MSG_Remove_DC_Clamp             ((uint16_t) 0x191)
#define PPSMC_MSG_Remove_DC_Clamp             ((uint16_t) 0x191)
#define PPSMC_MSG_SetFanPwmMax                ((uint16_t) 0x19A)


#define PPSMC_MSG_API_GetSclkFrequency        ((uint16_t) 0x200)
#define PPSMC_MSG_API_GetSclkFrequency        ((uint16_t) 0x200)
#define PPSMC_MSG_API_GetMclkFrequency        ((uint16_t) 0x201)
#define PPSMC_MSG_API_GetMclkFrequency        ((uint16_t) 0x201)
+8 −0
Original line number Original line Diff line number Diff line
@@ -96,6 +96,14 @@ typedef struct _ATOM_PPLIB_FANTABLE2
    USHORT  usTMax;                          // The max temperature
    USHORT  usTMax;                          // The max temperature
} ATOM_PPLIB_FANTABLE2;
} ATOM_PPLIB_FANTABLE2;


typedef struct _ATOM_PPLIB_FANTABLE3
{
	ATOM_PPLIB_FANTABLE2 basicTable2;
	UCHAR ucFanControlMode;
	USHORT usFanPWMMax;
	USHORT usFanOutputSensitivity;
} ATOM_PPLIB_FANTABLE3;

typedef struct _ATOM_PPLIB_EXTENDEDHEADER
typedef struct _ATOM_PPLIB_EXTENDEDHEADER
{
{
    USHORT  usSize;
    USHORT  usSize;
Loading