svn commit: r279045 - head/sys/powerpc/powermac
Justin Hibbits
jhibbits at FreeBSD.org
Fri Feb 20 06:19:25 UTC 2015
Author: jhibbits
Date: Fri Feb 20 06:19:23 2015
New Revision: 279045
URL: https://svnweb.freebsd.org/changeset/base/279045
Log:
Make the PowerMac fan control nonlinear
Summary:
Currently, fan control is linear between the target temperature and max
temperature, which is far from ideal. This changes it to be proportional to the
distance between the current temperature and the two endpoints (target and max
temp). This also adds a hysteresis, so that fans keep going when the
temperature drops, for about 10 seconds, before slowing down.
Reviewers: nwhitehorn
Reviewed By: nwhitehorn
Differential Revision: https://reviews.freebsd.org/D1549
MFC after: 3 weeks
Modified:
head/sys/powerpc/powermac/powermac_thermal.c
Modified: head/sys/powerpc/powermac/powermac_thermal.c
==============================================================================
--- head/sys/powerpc/powermac/powermac_thermal.c Fri Feb 20 06:13:52 2015 (r279044)
+++ head/sys/powerpc/powermac/powermac_thermal.c Fri Feb 20 06:19:23 2015 (r279045)
@@ -42,6 +42,9 @@ __FBSDID("$FreeBSD$");
#include "powermac_thermal.h"
+/* A 10 second timer for spinning down fans. */
+#define FAN_HYSTERESIS_TIMER 10
+
static void fan_management_proc(void);
static void pmac_therm_manage_fans(void);
@@ -63,6 +66,7 @@ static MALLOC_DEFINE(M_PMACTHERM, "pmact
struct pmac_fan_le {
struct pmac_fan *fan;
int last_val;
+ int timer;
SLIST_ENTRY(pmac_fan_le) entries;
};
struct pmac_sens_le {
@@ -95,6 +99,7 @@ pmac_therm_manage_fans(void)
struct pmac_sens_le *sensor;
struct pmac_fan_le *fan;
int average_excess, max_excess_zone, frac_excess;
+ int fan_speed;
int nsens, nsens_zone;
int temp;
@@ -137,10 +142,11 @@ pmac_therm_manage_fans(void)
nsens = nsens_zone = 0;
average_excess = max_excess_zone = 0;
SLIST_FOREACH(sensor, &sensors, entries) {
- frac_excess = (sensor->last_val -
+ temp = imin(sensor->last_val,
+ sensor->sensor->max_temp);
+ frac_excess = (temp -
sensor->sensor->target_temp)*100 /
- (sensor->sensor->max_temp -
- sensor->sensor->target_temp);
+ (sensor->sensor->max_temp - temp + 1);
if (frac_excess < 0)
frac_excess = 0;
if (sensor->sensor->zone == fan->fan->zone) {
@@ -166,9 +172,21 @@ pmac_therm_manage_fans(void)
* Scale the fan linearly in the max temperature in its
* thermal zone.
*/
- fan->fan->set(fan->fan, max_excess_zone *
+ max_excess_zone = imin(max_excess_zone, 100);
+ fan_speed = max_excess_zone *
(fan->fan->max_rpm - fan->fan->min_rpm)/100 +
- fan->fan->min_rpm);
+ fan->fan->min_rpm;
+ if (fan_speed >= fan->last_val) {
+ fan->timer = FAN_HYSTERESIS_TIMER;
+ fan->last_val = fan_speed;
+ } else {
+ fan->timer--;
+ if (fan->timer == 0) {
+ fan->last_val = fan_speed;
+ fan->timer = FAN_HYSTERESIS_TIMER;
+ }
+ }
+ fan->fan->set(fan->fan, fan->last_val);
}
}
More information about the svn-src-all
mailing list