Yes thats the same i have and it is working with my latest patches for dts. Daniel will add them to openwrt too.
PWM is working now? Sweet.
Pwm was basicly already working,but we missed a patch for the fan socket in dts and enabling pwm itself.
I’m rusty on Device Tree. I think the current R4’s DTS is quite wrong about trip points and cooling mapping. The fan won’t work as expected.
Perhaps that’s the reason one user above tried to do it himself in Linux user space ? Akin to run a program on Windows eating CPU cycles to manage fan speed.
If I read the current DTS correctly, here are current fan speed & trip point setup:
fan level: 0 - duty cycle 0%, 1 - 30%, 2 - 50%, 3 100%
Trip points: low - 40C, med - 85C, high - 115C, hot - 120C, critical - 125C
trip point to fan level mapping: low <> 1 1, med <> 2 2, hot <> 3 3
I see four main issues:
- 40C is too low a temperature to start the fan and potentially associated noise. Router chips can tolerate lot higher temperature.
- Once the fan triggered it will never stop, even if temperature drops below 40C.
- No “passive” trip point. Note I think “passive” is not what the author thinks i.e. heat dissipation by heatsink. A “passive” trip point in DTS is cooling by adjusting CPU freq.
- CPU freq won’t throttle when overheat as a “passive” mapping is missing.
I haven’t got R4 yet and no chance to try. My recommended trip points:
Trip points: low - 65C, med - 70C, high - 80C, hot - 95C (define this trip point as “passive”), critical - 125C
And the trip points to fan level mapping should be:
low <> 0 1, med <> 1 2, high <> 2 3, hot <> 3 3
Add the missing mapping for ‘hot’ that linking to CPU OPPs for “passive” cooling
With these changes, the behaviour will be:
- 65C or below: fan not spin
- 70C or below: 0% to 30% duty cycle
- 80C or below: 30% to 50% duty cycle
- 95C or below: 50% to 100% full blast; additionally use CPU throttle to reduce heat
- 125C: system auto reboot (I believe it’s hard wired inside the SoC).
Reference to Device Tree: https://www.kernel.org/doc/Documentation/devicetree/bindings/thermal/thermal.txt
I have not changed temperatures for fan yet, so i see them as some test values…especially the lowest one…40 is a bit low and reached fast after bootup. I would say 60 or 55 would be a good choice.
I have not done tests for cpu-freq yet because i’m no expert here,but i saw driver change.
@dangowrt what do you think? Any tests with cpufreq yet?
Autoreboot is set in thermal driver (lvts) with a security space like on other SoCs…afair at 115°C
Going to play on it once I got my hands on R4 hardware. Sounds fun and hopefully will have something useful coming out of it.
I saw following patch in openwrt.git shortlog:
mediatek: fix PWM fan on BPi-R4
I rebuilt the snapshot, but unfortunately the fan still always spinning. I’m using:
cat /sys/class/thermal/thermal_zone0/temp
to read the temperature and
echo 47000 > /sys/class/thermal/thermal_zone0/trip_point_2_temp
to write the temp threshold. When I read the status:
cat /sys/class/thermal/cooling_device0/cur_state
it is reporting 0 (fun off), but fun is still spinning.
Have you looked what trip_point2 is? Afaik you have to change trip_point 4 or 3 as these are the lowest trips
Hi Frank, I did not know about ne two more trip points. Thanks However I set in thermal_zone_0:
trip_point 0 to 80000
trip_point 1 to 70000
trip_point 2 to 56000
trip_point 3 to 55000
trip_point 4 to 54000
temperature of thermal_zone_0 is 33122 and fan still spinning. Status of “cooling device 0” still 0 off but spinning. Seems trip points not working or I’m doing something wrong. Also set trip point 4 to 30000 and the status went to 1 (fan on) So it seems the status 0 is not interrupting the power on fan plug.
Yes thats what i have expected…whats wrong here?
Why should it do that? Thermal trips handling fan nothing else yet…maybe we get passive (cpu trotteling) cooling working.
The emergency shotdown is hardcoded in lvts driver at 115°C
In BPI-R3 the trip point_2 was the threshold for the fan to spin or not. When temeperature more than the theshold it was spinning when under the threshold the fan was not spinning. In BPI-R4 always spinning at the same maximum speed. May be I do not understand how PWM works… Changing the rotation speed according to the various trip points? A mistery for me… Frank clarify how should work.
Create a shell command file and write these into shell command file:
if [ -d /sys/devices/pwm-fan ]; then
FAN_CTRL=/sys/devices/pwm-fan/hwmon/hwmon0/pwm1
elif [ -d /sys/devices/platform/pwm-fan ]; then
FAN_CTRL=/sys/devices/platform/pwm-fan/hwmon/hwmon0/pwm1
else
exit 0
fi
run this shell file:
chmod +x yourFileName.sh && ./yourFileName.sh
finally use this command:
echo 180 > /sys/devices/platform/pwm-fan/hwmon/hwmon0/pwm1
Hello i have used echo 180 > /sys/devices/platform/pwm-fan/hwmon/hwmon0/pwm1 then my fan go up. after a few seconds its go back to 80. its look like a fancontrol is active. is the fan controlled by the driver or by a linux programm? and can i change the settings?
BTW: If you’re curious about that open-top case: That’s a parametric OpenSCAD 3D-printable case I’m working on. I’ll post it here (and Github) when it’s done (still haven’t coded the front plate yet). When it’s done you’ll be able to specify how much space you want above/below the board, whether and where you want antenna holes, whether or not to include various mounting options, etc. Neat feature: I made it so you can feel/press the WPS and Reset buttons via little flexure tabs/buttons (no need to get a needle hehe)
A very old comment I just stumbled across, but did you ever get the case finished or still have the files for however far you got on it you’d share?
BPI R4 over-temperature reboot will slow down the fan speed, I recommend writing
echo 180 > /sys/devices/platform/pwm-fan/hwmon/hwmon0/pwm1
script to the /etc/rc.local file
I am using the Banana Pi Ubuntu 24.04 for this board and looking for a way to control the CPU heat sink fan speed.
FWIW, I came across a shell script in the BPI-R4 doc, scroll down to Heat sink
in the link below:
Caveat: you may have to change some of the filenames in the script, based on what the kernel creates:
# ls -l /sys/class/pwm/pwmchip0/
device/ export npwm power/ subsystem/ uevent unexport
Hope this helps
Anyone got PWM6 working? That’s the one on the header pin 7 (not the PWM0 used for CPU fan control). I’ve exported every available PWM chans (1 to 7) and tried setting different value to period/duty_cycle/enable without any success.
I can control same pin as the GPIO62 (512+62=574 channel in the sysfs) through the sysfs, it works by setting OUTPUT direction and by setting or clearing bit level goes HIGH/LOW.
But if I try to change those values on any/all of the PWM channels, pin just stays at the same level it was. If I try to control it after reboot, it stays in the HI-Z (INPUT ?), if I try to set it HIGH or LOW via GPIO controls, it stays there. Either it’s something missing on the DTS, or wrong registers in the driver… or well I’m doing something wrong.
PS: pwm0 channel doesn’t exports, which is fine because it’s taken by hwmon for pwmfan. But I doubt it can affect other channels, because they are exported just fine and channel 0 reports it’s busy on an attempt to export.
Answering myself. Sounds like this recent commit might fix the issue: mediatek: pinctrl-mt7988: add missing PWM pingroups · openwrt/openwrt@2cbd230 · GitHub Noticed that pin 62 was just added by this commit for PWM6 function. Will try it soon.
I finally got it working. Spent a lot of time trying to figure it out because I wasn’t familiar with the pinctrl/pinmux sysfs interface and a weird thing that in fact pinmux-pins in the sysfs holds only boot-time information on pins configs. If you select function for a pin group via pinmux-select nothing just seems to happen. Not a single message in dmesg (while it will log an error if you put incorrect group/function name) and pinmux-pins pseudofile still reads as “pin 62 (JTAG_JTRST_N): UNCLAIMED”. But in fact, if you just ignore it and go to the pwm sysfs interface, export pwm6, set period/duty/enable it will be running normally. I’ve read generated PWM values with multimeter and it reads exactly the same frequency/duty cycle (and an average voltage) values, as I expect from my settings.
Pinmux controls located in the /sys/kernel/debug/pinctrl/1001f000.pinctrl-pinctrl_moore and the PWM control at /sys/class/pwm/pwmchip0
How to enable PWM6 on GPIO62 pin. You’ll need to be on the very latest snapshot at the moment. Commit I’ve mentionned above adds new pwmN_0 groups, and PWM6 function on GPIO62 pin are on the pwm6_0 group. You can check every available pin group and function by reading /sys/kernel/debug/pinctrl/1001f000.pinctrl-pinctrl_moore/pinmux-functions.
echo "pwm6_0 pwm" > /sys/kernel/debug/pinctrl/1001f000.pinctrl-pinctrl_moore/pinmux-select # Enable PWM function on the pin group pwm6_0 (GPIO62)
echo 6 > /sys/class/pwm/pwmchip0/export # export PWM ch 6 to the sysfs interface
echo 100000 > /sys/class/pwm/pwmchip0/pwm6/period # Set freq to 10 kHz (100000 ns period)
echo 40000 > /sys/class/pwm/pwmchip0/pwm6/duty_cycle # Set duty cycle to 40% (40000 ns active)
echo 1 > /sys/class/pwm/pwmchip0/pwm6/enable # Run PWM
/sys/kernel/debug/pinctrl/1001f000.pinctrl-pinctrl_moore/pinmux-pins provides useful info, but remember it only holds boot-time values (probably from DTS) and won’t change to reflect live adjustments. Other files there provide some other useful info, everything except for the pinmux-select are read-only text info so it’s safe to cat them.
Side effect: I was curious how much current load a GPIO pin of the MT7988 can source/sink. Read through open datasheet and registers but it lists only voltage range in electrical characteristcs chapter and no references to max current at all. But I was surprised to find out that the values are reported in the pinconf-pins file of the pinctrl sysfs interface. For those who might be interested it reports 4mA for every GPIO pin for me. This:
root@BPI-R4:~# head -n3 /sys/kernel/debug/pinctrl/1001f000.pinctrl-pinctrl_moore
/pinconf-pins
Pin config settings per pin
Format: pin (name): configs
pin 0 (UART2_RXD): input bias pull up (102 ohms), output drive strength (4 mA), input enabled, input schmitt enabled, pu-adv (2)
Output drive strength are the same for every GPIO pin. But it changes in input values, at least in pull direction (up/down) and resistance.