RPi CM4 新增晶片元件的dts 修改dts 以TPM NPCT750 為例
前言
本篇內容主要介紹如果dtoverlay中沒有你的晶片型號或模組型號,該如何快速撰寫dts建立自己的設備樹。
前提準備
- 一塊已經裝好RPi OS的樹梅派板子。
- 下載好rpi linux kernel source code
確認你的設備晶片是否有dts可以直接使用
我們知道要開啟spi或是設定pin腳位功能或是使用了某些晶片元件,需要修改/boot/config.txt檔案~ 如果你還不知道怎麼開啟spi功能與設定pin腳位功能的話可以參考我這篇文章~這邊假設你已經啟用spi功能了。
假設我現在的RPi板子上接上一些額外的元件,我們要先查詢該元件的型號是什麼。假設型號是MCP251xFD的SPI to CAN Bus的晶片~我們在使用底下指令來查看是否有已經寫好的dts可以直接使用。
~$ dtoverlay -a |grep mcp251
mcp2515
mcp2515-can0
mcp2515-can1
mcp251xfd
經過查詢發現到mcp251xfd,再來我們要詳細看他的參數有哪些怎麼設定。請輸入底下指令。
~$ dtoverlay -h mcp251xfd
Name: mcp251xfd
Info: Configures the MCP251XFD CAN controller family
For devices on spi1 or spi2, the interfaces should be enabled
with one of the spi1-1/2/3cs and/or spi2-1/2/3cs overlays.
Usage: dtoverlay=mcp251xfd,<param>=<val>
Params: spi<n>-<m> Configure device at spi<n>, cs<m>
(boolean, required)
oscillator Clock frequency for the CAN controller (Hz)
speed Maximum SPI frequence (Hz)
interrupt GPIO for interrupt signal
rx_interrupt GPIO for RX interrupt signal (nINT1) (optional)
xceiver_enable GPIO for CAN transceiver enable (optional)
xceiver_active_high specifiy if CAN transceiver enable pin is
active high (optional, default: active low)
再來就是依照參數說明做設定,如果還想要知道MCP251xFD這些參數怎麼設定的話可以參考我這篇文章
底下要直接說明如果dtoverlay查詢不到對應的晶片元件該如何自己建立dts!!
建立dts 自己寫晶片元件的dts
如果有人已經寫好的dts當然使用別人寫好的比較快速方便,但如果今天你要使用的晶片沒有人寫dts呢?如下我舉例現在要使用tpm-npct750。
~$ dtoverlay -a |grep tpm
tpm-slb9670
tpm-slb9673
從型號中可以發現沒有NPCT750的型號。
我們直接參考類似的晶片元件dts,如tpm-slb9670~ link
/*
* Device Tree overlay for the Infineon SLB9670 Trusted Platform Module add-on
* boards, which can be used as a secure key storage and hwrng.
* available as "Iridium SLB9670" by Infineon and "LetsTrust TPM" by pi3g.
*/
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <&spi0>;
__overlay__ {
status = "okay";
};
};
fragment@1 {
target = <&spidev1>;
__overlay__ {
status = "disabled";
};
};
fragment@2 {
target = <&spi0>;
__overlay__ {
/* needed to avoid dtc warning */
#address-cells = <1>;
#size-cells = <0>;
slb9670: slb9670@1 {
compatible = "infineon,slb9670";
reg = <1>; /* CE1 */
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <32000000>;
status = "okay";
};
};
};
};
依照電路圖我可以得知我的TPM SPI是接到RPi的SPI1、Chip Select 1。 所以我把上面的dts中的
target = <&spi0>改成target = <&spi1>因為是接到SPI1
target = <&spidev1>改成target-path = “spi1/spidev@1” 這段是要關閉spi dev讓她不會再user space 底下長出/dev/spi設備樹出來,該SPI1 CS1已經被NPCT750佔用了所以必須關閉,前者target = <&spidev1>是spi0的spi dev CS1,後者target-path = “spi1/spidev@1”是spi1的spi dev CS1,如果這裡沒有把他disabled的話,會有錯誤訊息說spi dev is in use無法建立/dev/spi1.1。
再來npct750: npct750@1 :前面是label,:後面是node-name 皆為自訂義的名稱,當然我們會寫晶片的型號好讓別人容易理解,@後面是unit-addess,代表節點位置,而且必須要跟reg<>裡面的第一個數值一致,這邊因為我們是Chip Select 1所以數值就是1,你要問我怎麼知道這些規範,請參考device tree spec 第2.2.1節
而compatible的格式是”manufacturer,model”,前者是晶片製造商,後者是晶片driver型號。 這邊我們通常會去找tpm driver source code的.compatible定義~
//tpm_tis_spi_main.c
static const struct of_device_id of_tis_spi_match[] __maybe_unused = {
{ .compatible = "st,st33htpm-spi", .data = tpm_tis_spi_probe },
{ .compatible = "infineon,slb9670", .data = tpm_tis_spi_probe },
{ .compatible = "tcg,tpm_tis-spi", .data = tpm_tis_spi_probe },
{ .compatible = "google,cr50", .data = cr50_spi_probe },
{}
};
從driver source code 我們知道有四個選項,而且我們發現前三個都是呼叫同一個function call tpm_tis_spi_probe,所以其實寫哪三個都一樣,但是為了命名原則我們還是會選用TCG specification 這個標準通用型的。網路上也查到此敘述。
Chip: Nuvoton NPCT750, compliant with TCG specification Family “2.0” Rev1.38
最後就是spi-max-frequency這個要去看你晶片的datasheet,頻率不能超過晶片支援的最大頻率。
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <&spi1>;
__overlay__ {
status = "okay";
};
};
fragment@1 {
target-path = "spi1/spidev@1";
__overlay__ {
status = "disabled";
};
};
fragment@2 {
target = <&spi1>;
__overlay__ {
/* needed to avoid dtc warning */
#address-cells = <1>;
#size-cells = <0>;
npct750: npct750@1 {
compatible = "tcg,tpm_tis-spi";
reg = <1>; /* CE1 */
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <1000000>;
status = "okay";
};
};
};
};
編譯dts成dtbo
把剛剛改好的檔案命名好正確的檔名放到/home/caspar/linux/arch/arm64/boot/dts/overlays底下。
~$ cp tpm-npct750-overlay.dts ~/linux/arch/arm64/boot/dts/overlays
進到~/linux/arch/arm64/boot/dts/overlays修改Makefile
$ cd ~/linux/arch/arm64/boot/dts/overlays
$ vim Makefile
移到最下面新增底下程式tpm-npct750.dtbo
waveshare-can-fd-hat-mode-a.dtbo \
waveshare-can-fd-hat-mode-b.dtbo \
wittypi.dtbo \
wm8960-soundcard.dtbo \
tpm-npct750.dtbo
targets += dtbs dtbs_install
targets += $(dtbo-y)
開始編譯
$ cd ~/linux
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- dtbs
DTCO arch/arm64/boot/dts/overlays/tpm-npct750.dtbo
最後把編譯出來的tpm-npct750.dtbo放到板子內的/boot/overlays/內
並且修改/boot/config.txt加上這行
# Enable TPM2.0
dtoverlay=tpm-npct750
結語
學會新增dts之後開發其他板子會更容易上手~
留言