はじめに
KV260 には ZynqMP チップを冷却するためのファンがついています。この冷却ファンを Debian/Ubuntu から制御するための方法を3回に分けて説明します。今回はその2回目です。
ttc driver
概要
この章では ttc driver の説明をします。ttc driver はソフトウェア/ハードウェアスタックのうちシェードのかかった部分です。
Fig.1 KV260 Fan Control Stack (ttc driver)
ttc driver はZynqMP に搭載されている TTC(Triple Timer Counter) モジュールを制御するための Linux Kernel Module です。
Kconfig
ttc driver を Linux Kernel に組み込むためには CONFIG_PWM_CADENCE に y または m を設定する必要があります。これは linux のソースコードの drivers/pwm/Kconfig に定義されています。
config PWM_CADENCE
tristate "Cadence PWM support"
depends on OF
depends on COMMON_CLK
help
Generic PWM framework driver for cadence TTC IP found on
Xilinx Zynq/ZynqMP/Versal SOCs. Each TTC device has 3 PWM
channels. Output of 0th PWM channel of each TTC device can
be routed to MIO or EMIO, and output of 1st and 2nd PWM
channels can be routed only to EMIO.
紛らわしいのですが、drivers/clocksource にも TTC を制御するためのドライバが存在します。こちらは CONFIG_CADENCE_TTC_TIMER に y または m を設定すると使えるようになるのですが、ZynqMP の場合はこちらを使わないので、CONFIG_CADENCE_TTC_TIMER を設定してはいけません。
Device Tree
ZynqMP が搭載されたシステム用のデバイスツリーを作る際、まずzynqmp.dtsi がインクルードされます。これには ZynqMP 独自の設定やZynqMP が持っている各種モジュールのデバイスツリーのノードが設定されています。そして ttc0 関連の記述は次のようになっています。
ttc0: timer@ff110000 {
compatible = "cdns,ttc";
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 36 4>, <0 37 4>, <0 38 4>;
reg = <0x0 0xff110000 0x0 0x1000>;
timer-width = <32>;
power-domains = <&zynqmp_firmware PD_TTC_0>;
};
ここには、ロードするカーネルモジュール名、割り込みの設定、レジスタのアドレスの設定などが定義されています。ただし、status が "disabled" になっている事に注意してください。このままではこのドライバは有効になりません。このドライバを有効にするためには、各ボードごとに個別に設定する必要があります。例えば、KV260 に搭載されている SOM 用のデバイスツリーでは zynqmp.dtsi をインクルードした後に次のようにして ttc0 用のドライバを有効にしています。
/dts-v1/;
#include "zynqmp.dtsi"
:
(中略)
: :
&ttc0 {
status = "okay";
#pwm-cells = <3>;
};
:
(後略)
pwm-fan
概要
この章では pwm-fan の説明をします。pwm-fan は ソフトウェア/ハードウェアスタックのうちシェードのかかった部分です。
Fig.2 KV260 Fan Control Stack (pwm-fan)
pwm-fan は PWM 制御機能付きファンを制御するためのドライバです。このドライバは、Linux Hardware Monitoring Kernel API (通称 hwmon) に対応しています。hwmon はハードウェア監視デバイスと通信するためにユーザー空間で使用できる API を提供します。この API は /sys/class/hwmon 経由でアクセスします。
Kconfig
pwm-fan を Linux Kernel に組み込むためにはCONFIG_SENSORS_PWM_FAN に y または m を設定する必要があります。これは linux のソースコードの drivers/hwmon/Kconfig に定義されています。
config SENSORS_PWM_FAN
tristate "PWM fan"
depends on (PWM && OF) || COMPILE_TEST
depends on THERMAL || THERMAL=n
help
If you say yes here you get support for fans connected to PWM lines.
The driver uses the generic PWM interface, thus it will work on a
variety of SoCs.
This driver can also be built as a module. If so, the module
will be called pwm-fan.
Device Tree
KV260 で pwm-fan を有効にするためには、デバイスツリーで有効にしておく必要があります。例えば、KV260 に搭載されている SOM 用のデバイスツリーでは次のように記述されています。
/dts-v1/;
#include "zynqmp.dtsi"
#include "zynqmp-clk-ccf.dtsi"
#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/phy/phy.h>
#include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
/ {
:
(中略)
: :
pwm-fan {
compatible = "pwm-fan";
status = "okay";
pwms = <&ttc0 2 40000 0>;
};
};
:
(後略)
pwms プロパティで、対応する pwm ドライバを指定します。
pwms プロパティの第一引数には使用する pwm ドライバを指定します。ZynqMP では ttc0 に pwm ドライバを使っているのでttc0 のシンボルを指定します。
pwms プロパティの第二引数には使用するttc のチャネル番号を指定します。ttc0 には0から2までの3チャネルありますが、『Debian/Ubuntu でKV260 で冷却ファンを制御する (その1)』 @Qiita で説明したビットストリームでは2チャネル目の波形出力を使うため、ここでは2を指定します。
pwms プロパティの第三引数はPWMの周期をしています。ttc0 に入力されているクロックの周波数は 100MHz なので 2.5KHz かな?
pwms プロパティの第四引数は極性だそうです。
動作確認
この投稿で説明したドライバを有効にした Linux Kernel を使って KV260 を起動してから、『Debian/Ubuntu でKV260 で冷却ファンを制御する (その1)』 @Qiita で説明したビットストリームをPL部にプログラムします。
この時点で /sys/class/hwmon の下に hwmon[数字] みたいな名前のドライバがみえます。そのうちの一つが pwmfan です。この例では hwmon2 が pwmfan だとします。
root@ubuntu-fpga:~# ls -la /sys/class/hwmon/hwmon2/
total 0
drwxr-xr-x 3 root root 0 Mar 20 23:32 .
drwxr-xr-x 3 root root 0 Mar 20 23:32 ..
lrwxrwxrwx 1 root root 0 Mar 20 23:32 device -> ../../../pwm-fan
-r--r--r-- 1 root root 4096 Mar 20 23:32 name
lrwxrwxrwx 1 root root 0 May 23 12:32 of_node -> ../../../../../firmware/devicetree/base/pwm-fan
drwxr-xr-x 2 root root 0 May 23 12:32 power
-rw-r--r-- 1 root root 4096 May 23 12:31 pwm1
lrwxrwxrwx 1 root root 0 May 23 12:32 subsystem -> ../../../../../class/hwmon
-rw-r--r-- 1 root root 4096 Mar 20 23:32 uevent
name を確認して pwmfan ならOk です。
root@ubuntu-fpga:~# cat /sys/class/hwmon/hwmon2/name
pwmfan
試しに pwm1 に20くらいの値を設定してみます。これでファンが静かにゆっくり回転するようになるか確認してください。
root@ubuntu-fpga:~# echo 20 > /sys/class/hwmon/hwmon2/pwm1
次に pwm1 に255 を設定してみます。ファンがフル回転しだすはずです。
root@ubuntu-fpga:~# echo 255 > /sys/class/hwmon/hwmon2/pwm1
pwm1 に0を設定するとファンが停止するかと思いきや、何故かフル回転します。これはちょっと直感的じゃないです。
root@ubuntu-fpga:~# echo 0 > /sys/class/hwmon/hwmon2/pwm1
pwm1 に 1 以上 10 以下の値を設定するとファンが停止します。
root@ubuntu-fpga:~# echo 10 > /sys/class/hwmon/hwmon2/pwm1