Я решил это !!!!! Может быть, это нечто тривиальное, но для меня это было очень сложно, и я многому научился. Существует много информации о том, как это сделать в Pandaboard, только для Beagleboards. Итак, во-первых, файл Device Tree Overlay
загружен только при загрузке, мы не можем загружать его динамически, как в Beagleboard, потому что у нас нет bone_capemgr
. Скомпилированный файл .dtb
находится в /boot/dtbs
(по крайней мере, в Arch Linux), есть много файлов .dtb
, но только один загружается при загрузке в зависимости от платы, и вы можете видеть, какая из них загружается при загрузке, например, в мой случай это:
U-Boot 2015.04 (Jun 07 2015 - 19:26:06) Arch Linux ARM
CPU : OMAP4460 ES1.1
Board: OMAP4 Panda
I2C: ready
DRAM: 1 GiB
MMC: OMAP SD/MMC: 0
** Unable to use mmc 0:1 for loading the env **
Using default environment
Net: No ethernet found.
Hit any key to stop autoboot: 0
starting USB...
USB0: USB EHCI 1.00
scanning bus 0 for devices... 3 USB Device(s) found
scanning usb for storage devices... 0 Storage Device(s) found
scanning usb for ethernet devices... 1 Ethernet Device(s) found
switch to partitions #0, OK
mmc0 is current device
mmc found on device 0
Checking for: /boot/uEnv.txt ...
74 bytes read in 13 ms (4.9 KiB/s)
Loaded environment from /boot/uEnv.txt
Checking if uenvcmd is set ...
4984312 bytes read in 244 ms (19.5 MiB/s)
loading /boot/dtbs/omap4-panda-es.dtb ...
100695 bytes read in 380 ms (257.8 KiB/s)
** File not found /boot/initramfs-linux.img **
Kernel image @ 0x82000000 [ 0x000000 - 0x4c0df8 ]
## Flattened Device Tree blob at 88000000
Booting using the fdt blob at 0x88000000
Loading Device Tree to 8ffe4000, end 8ffff956 ... OK
Starting kernel ...
у меня есть Pandaboard ES, так что загруженный файл /boot/dtbs/omap4-panda-es.dtb
. Я декомпилировал файл, чтобы добавить настройки UART4 MUX с помощью dtc -I dtb -O dts omap4-panda-es.dtb > omap4-panda-es.dts
(взято из here). Итак, теперь у нас есть omap4-panda-es.dts
, который является полным наложением дерева устройств, который устанавливает все, мне просто нужно добавить настройки UART4 MUX. Мы должны использовать свойство pinctrl-single,pins
. Here действительно хорошее объяснение о pinctrl-single,pins
:
Штифт узлы конфигурации для pinctrl-сингл определены как pinctrl регистр смещения и пар значений с использованием pinctrl-сингл, булавки. Обновлены только биты, указанные в pinctrl-single, function-mask. Например, установка штыря для устройства может быть выполнена с помощью: pinctrl-single, pin = < 0xdc 0x118>; Где 0xdc - это смещение от базового адреса регистра pinkrl для регистра устройства pinctrl, а 0x118 содержит требуемое значение регистра pinctrl.
Это было что-то я не понял с самого начала, я хотя pinctrl
адрес был абсолютным, но это по отношению к базовому адресу в дереве. В моем случае, например, есть много pinmux_tfp410_pins
, pinmux_dss_hdmi_pins
, pinmux_i2c1_pins
и т. Д.Все эти pinmux_*
находятся под одним из родителей под названием [email protected]
, что означает, что адрес, указанный в pinctrl
является относительно 0x40
, но это [email protected]
находится под другим узлом называется [email protected]
, который находится внутри другого узла, называемого [email protected]
, так что адреса внутри [email protected]
являются относительно основания адрес узла, который является суммой всех этих адресов, то есть 0x4a000000 + 0x100000 + 0x40 = 0x4a100040
, поэтому 0xa100040
является базовым адресом, весь адрес, указанный в pinctrl
, относится к 0xa100040
. Так, согласно Таблица 18-504 в OMAP4 Technical Reference Manual
(доступен для скачивания here) адрес для управляющего регистра UART4, который управляет MUX, и некоторые другие вещи - 0x4A10015C
. Базовый адрес pinctrl: Адрес: pinctrl
Адрес: 0x11c
Адрес: 0x4a100040 + 0x11c = 0x4A10015C
. Все накладки дерева устройств, которые я нашел из других дистрибутивов linux, которые поддерживают Pandaboard, используют один и тот же базовый адрес (например, here). Поэтому я добавил в узле [email protected]
это:
// Set the UART4 MUX, it doesn't come by default so I had to add it
// "linux,phandle" has the same value aas "phandle", it's just a reference number, just make sure
// it is not being used in another part of the tree (it will refuse to compile if you do it wrong)
// The phandle is used for reference in "[email protected]" at "pinctrl-0"
pinmux_uart4_pins {
pinctrl-single,pins = <
0x11c 0x100 // uart4_rx.uart4_rx INPUT | MODE0
0x11e 0 // uart4_tx.uart4_tx OUTPUT | MODE0
>;
linux,phandle = <0xfff>;
phandle = <0xfff>;
};
Я принял эти настройки из here, но только изменяя 0x100
и 0
изменит настройки в реестре. В моем случае я должен был добавить:
linux,phandle = <0xfff>;
phandle = <0xfff>;
Я не вижу этого в Ubuntu, например (https://github.com/Canonical-kernel/Ubuntu-kernel/blob/master/arch/arm/boot/dts/omap4.dtsi), но я не знаю, почему и какова цель этого phandle
, все, что я знаю, что они используются как ссылка, ссылка, которую мне нужно поместить где-то еще в Дереве устройств, просто убедитесь, что она уникальна, она может быть любым 32-битным значением, но должна быть уникальной внутри дерева. В моем случае был другой узел со ссылкой UART4:
[email protected] {
compatible = "ti,omap4-uart";
reg = <0x4806e000 0x100>;
interrupts = <0x0 0x46 0x4>;
ti,hwmods = "uart4";
clock-frequency = <0x2dc6c00>;
interrupts-extended = <0x1 0x0 0x46 0x4 0x82 0x11c>;
linux,phandle = <0x121>;
phandle = <0x121>;
};
Так что я должен был использовать phandle
иначе MUX настройки не будут применены:
[email protected] {
compatible = "ti,omap4-uart";
reg = <0x4806e000 0x100>;
interrupts = <0x0 0x46 0x4>;
ti,hwmods = "uart4";
pinctrl-names = "default";
pinctrl-0 = <0xfff>;
clock-frequency = <0x2dc6c00>;
interrupts-extended = <0x1 0x0 0x46 0x4 0x82 0x11c>;
linux,phandle = <0x121>;
phandle = <0x121>;
};
Наконец, в конце файла есть много определений, один для каждого узла, например
i2c1_pins = "/ocp/[email protected]/[email protected]/[email protected]/pinmux_i2c1_pins";
i2c2_pins = "/ocp/[email protected]/[email protected]/[email protected]/pinmux_i2c2_pins";
i2c3_pins = "/ocp/[email protected]/[email protected]/[email protected]/pinmux_i2c3_pins";
i2c4_pins = "/ocp/[email protected]/[email protected]/[email protected]/pinmux_i2c4_pins";
wl12xx_gpio = "/ocp/[email protected]/[email protected]/[email protected]/pinmux_wl12xx_gpio";
wl12xx_pins = "/ocp/[email protected]/[email protected]/[email protected]/pinmux_wl12xx_pins";
twl6030_pins = "/ocp/[email protected]/[email protected]/[email protected]/pinmux_twl6030_pins";
Они просто описывают, где каждый узел расположен, здесь мы можем ясно видеть, что базовый адрес. Так вот, я просто добавил следующее:
uart4_pins = "/ocp/[email protected]/[email protected]/[email protected]/pinmux_uart4_pins";
Теперь у нас есть полный .dts
файл, который должен получить UART4 работать. Мы должны скомпилировать его с помощью dtc -O dtb -o omap4-panda-es.dtb -b O [email protected] omap4-panda-es.dts
, это приведет к созданию файла .dtb
, который заменит его в /boot/dtbs
, поэтому замените его и перезагрузите! После перезагрузки запустить cat /sys/kernel/debug/pinctrl/4a100040.pinmux/pinmux-functions
, он должен показать что-то вроде этого:
function: pinmux_dss_dpi_pins, groups = [ pinmux_dss_dpi_pins ]
function: pinmux_tfp410_pins, groups = [ pinmux_tfp410_pins ]
function: pinmux_dss_hdmi_pins, groups = [ pinmux_dss_hdmi_pins ]
function: pinmux_tpd12s015_pins, groups = [ pinmux_tpd12s015_pins ]
function: pinmux_hsusbb1_pins, groups = [ pinmux_hsusbb1_pins ]
function: pinmux_uart4_pins, groups = [ pinmux_uart4_pins ]
function: pinmux_wl12xx_pins, groups = [ pinmux_wl12xx_pins ]
function: gpio_led_pmx, groups = [ gpio_led_pmx ]
function: pinmux_wl12xx_gpio, groups = [ pinmux_wl12xx_gpio ]
function: pinmux_i2c1_pins, groups = [ pinmux_i2c1_pins ]
function: pinmux_twl6030_pins, groups = [ pinmux_twl6030_pins ]
function: pinmux_twl6040_pins, groups = [ pinmux_twl6040_pins ]
function: pinmux_i2c2_pins, groups = [ pinmux_i2c2_pins ]
function: pinmux_i2c3_pins, groups = [ pinmux_i2c3_pins ]
function: pinmux_i2c4_pins, groups = [ pinmux_i2c4_pins ]
function: pinmux_wl12xx_pins, groups = [ pinmux_wl12xx_pins ]
function: pinmux_mcpdm_pins, groups = [ pinmux_mcpdm_pins ]
function: pinmux_mcbsp1_pins, groups = [ pinmux_mcbsp1_pins ]
Если мы видим uart4
все в порядке, и он должен работать! В противном случае в файле .dts
есть что-то неправильное. Мы можем проверить, работает ли uart, например, echo -e "AT" > /dev/ttyO3
, что /dev/ttyO3
- UART4
. Надеюсь, это будет полезно для кого-то!
Просто для справки здесь полный .dts
и составлен .dtb
файл с рабочим UART4: https://gist.github.com/dragondgold/1aaabf93279006b703f3