Configure CPU FAN on ASRock DeskMini A300
Introduction
I finally decided to have a home server, where to put backups, virtual machines, and, as I’m a Gentoo user, build packages for my other hosts. My hardware decision for this, falls to ASRock DeskMini A300, but, as I decided to put this host in the middle of the living room, it must be quiet on idle use, and for this I bought also a FAN from noctua NH-L9a-AM4 to have a low noise and low profile fan inside my A300.
Using motherboard configurations
When I finished my build, I started Gentoo installation, but I soon noticed, that the firmware of the ASRock motherboard doesn’t fit my needs for CPU FAN profile, because I tried Standard profile, and this was fine for cooling, but not when the host was idle, because on that situation the CPU temperature goes under 30 degree, but the FAN’s RPM still goes at ~1400, witch is loudly in the silent living room; this is the configuration passed by the mobo firmware to Linux kernel hwmon module NCT6775 (I’ll describe later any details, don’t worry):
Auto Point | PWM | Temp (millidegree) |
---|---|---|
auto_point1 | 140 | 50000 |
auto_point2 | 165 | 60000 |
auto_point3 | 191 | 65000 |
auto_point4 | 216 | 70000 |
auto_point5 | 255 | 75000 |
you could see those values under the sysfs special files:
/sys/devices/platform/nct6775.656/hwmon/hwmon0/pwm2_auto_point1_pwm
/sys/devices/platform/nct6775.656/hwmon/hwmon0/pwm2_auto_point1_temp
/sys/devices/platform/nct6775.656/hwmon/hwmon0/pwm2_auto_point2_pwm
/sys/devices/platform/nct6775.656/hwmon/hwmon0/pwm2_auto_point2_temp
/sys/devices/platform/nct6775.656/hwmon/hwmon0/pwm2_auto_point3_pwm
/sys/devices/platform/nct6775.656/hwmon/hwmon0/pwm2_auto_point3_temp
/sys/devices/platform/nct6775.656/hwmon/hwmon0/pwm2_auto_point4_pwm
/sys/devices/platform/nct6775.656/hwmon/hwmon0/pwm2_auto_point4_temp
/sys/devices/platform/nct6775.656/hwmon/hwmon0/pwm2_auto_point5_pwm
/sys/devices/platform/nct6775.656/hwmon/hwmon0/pwm2_auto_point5_temp
instead, when I tried to use the motherboard Silent profile, I noticed that this was fine when the host is idle, but, for example when I started to compile some packages, the CPU raises warning temperatures close to 70 degrees, but the CPU FAN was still at ~1600-1800 RPM, because the firmware passed these values to NCT6775 hwmon module:
Auto Point | PWM | Temp (millidegree) |
---|---|---|
auto_point1 | 102 | 50000 |
auto_point2 | 114 | 60000 |
auto_point3 | 127 | 65000 |
auto_point4 | 153 | 75000 |
auto_point5 | 255 | 85000 |
Small explanation of HWMON data
Fortunately, A300’s mobo give me the opportunity to use the Smart Fan mode, using five slopes to control / calculate (in chip) the DC/PWM output for the CPU FAN, by simply write the desired PWM, from 0 (lowest speed) to 255 (full speed) to the corresponding slope millidegree, for example if you write 65 PWM in pwm2_auto_point1_pwm and 30000 millidegrees in pwm2_auto_point1_temp, then the module will set the pwm to 65 when the chip take the temperatures near to 30 degrees.
If you want additional information about hwmon and NCT6775 you can read:
Setting custom values for CPU FAN
To resolve this problem, and meet all my requirements, the solution was very simple, I just write inside those sysfs special files these values:
Auto Point | PWM | Temp (millidegree) |
---|---|---|
auto_point1 | 65 | 30000 |
auto_point2 | 110 | 40000 |
auto_point3 | 150 | 50000 |
auto_point4 | 210 | 60000 |
auto_point5 | 255 | 64000 |
shifting down the auto temperatures, because lisensors tell me that CPU critical temperature is 70 degrees and I saw the CPU under pressure raises 65-70 degrees really fast.
But setting those values needs some configurations
Optional - Build kernel with NCT6775 module
If you’re building your custom kernel like me, you’ll need to include the NCT6775 module
Device Drivers --->
{*} Hardware Monitoring support --->
<M> Nuvoton NCT6775F and compatibles
then rebuild your kernel and reboot with it.
Automatically load nct6775 module
Make sure to load nct6775 module at boot and for this you could simply create a file under systemd /etc/modules-load.d directory:
echo nct6775 >> /etc/modules-load.d/lm_sensors.conf
systemctl restart systemd-modules-load.service
Check hwmon data
Make sure your hwmon nct6775 module create the special files, in my case this is hwmon0 device and the CPU fan is detected as FAN2 with PWM2
cat /sys/class/hwmon/hwmon0/fan2_input
1421
ls /sys/class/hwmon/hwmon0/fan2*
/sys/class/hwmon/hwmon0/fan2_alarm /sys/class/hwmon/hwmon0/fan2_min /sys/class/hwmon/hwmon0/fan2_tolerance
/sys/class/hwmon/hwmon0/fan2_beep /sys/class/hwmon/hwmon0/fan2_pulses
/sys/class/hwmon/hwmon0/fan2_input /sys/class/hwmon/hwmon0/fan2_target
ls /sys/class/hwmon/hwmon0/pwm2*
/sys/class/hwmon/hwmon0/pwm2 /sys/class/hwmon/hwmon0/pwm2_mode
/sys/class/hwmon/hwmon0/pwm2_auto_point1_pwm /sys/class/hwmon/hwmon0/pwm2_start
/sys/class/hwmon/hwmon0/pwm2_auto_point1_temp /sys/class/hwmon/hwmon0/pwm2_step_down_time
/sys/class/hwmon/hwmon0/pwm2_auto_point2_pwm /sys/class/hwmon/hwmon0/pwm2_step_up_time
/sys/class/hwmon/hwmon0/pwm2_auto_point2_temp /sys/class/hwmon/hwmon0/pwm2_stop_time
/sys/class/hwmon/hwmon0/pwm2_auto_point3_pwm /sys/class/hwmon/hwmon0/pwm2_target_temp
/sys/class/hwmon/hwmon0/pwm2_auto_point3_temp /sys/class/hwmon/hwmon0/pwm2_temp_sel
/sys/class/hwmon/hwmon0/pwm2_auto_point4_pwm /sys/class/hwmon/hwmon0/pwm2_temp_tolerance
/sys/class/hwmon/hwmon0/pwm2_auto_point4_temp /sys/class/hwmon/hwmon0/pwm2_weight_duty_base
/sys/class/hwmon/hwmon0/pwm2_auto_point5_pwm /sys/class/hwmon/hwmon0/pwm2_weight_duty_step
/sys/class/hwmon/hwmon0/pwm2_auto_point5_temp /sys/class/hwmon/hwmon0/pwm2_weight_temp_sel
/sys/class/hwmon/hwmon0/pwm2_crit_temp_tolerance /sys/class/hwmon/hwmon0/pwm2_weight_temp_step
/sys/class/hwmon/hwmon0/pwm2_enable /sys/class/hwmon/hwmon0/pwm2_weight_temp_step_base
/sys/class/hwmon/hwmon0/pwm2_floor /sys/class/hwmon/hwmon0/pwm2_weight_temp_step_tol
Write PWM special files at boot
To write the PWM auto point special files I use my python changegovernor program, who I use also to automatically change CPU governor from powersave to performance, by simply adding those configurations in DEFAULTS stanza inside the changegovernor.json
{
"name": "DEFAULTS",
"state": "present",
"extra_commands": [
"echo 30000 > /sys/class/hwmon/hwmon0/pwm2_auto_point1_temp",
"echo 65 > /sys/class/hwmon/hwmon0/pwm2_auto_point1_pwm",
"echo 40000 > /sys/class/hwmon/hwmon0/pwm2_auto_point2_temp",
"echo 110 > /sys/class/hwmon/hwmon0/pwm2_auto_point2_pwm",
"echo 50000 > /sys/class/hwmon/hwmon0/pwm2_auto_point3_temp",
"echo 150 > /sys/class/hwmon/hwmon0/pwm2_auto_point3_pwm",
"echo 60000 > /sys/class/hwmon/hwmon0/pwm2_auto_point4_temp",
"echo 210 > /sys/class/hwmon/hwmon0/pwm2_auto_point4_pwm",
"echo 64000 > /sys/class/hwmon/hwmon0/pwm2_auto_point5_temp",
"echo 255 > /sys/class/hwmon/hwmon0/pwm2_auto_point5_pwm"
]
}
and here you can find the changegovernor.json file for my DeskMini A300, but you could also simply write a bash script to write your values inside sysfs special files.