Ok I solved it!!!!! Maybe is something trivial but it was really hard for
me but I learned a lot. There is no much info about how to do it in
Pandaboard, just for Beagleboards. So first, the Device Tree Overlay file
it's loaded only at *boot*, we can't load it dynamically as with
Beagleboard because we don't have a *bone_capemgr*. The compiled .dtb file
is located in */boot/dtbs* (at least in Arch Linux), there are a lot of
.dtb files there but only one is loaded at boot depending on the board and
you can see which one is loaded when booting, for example, in my case it is:
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 **
## Flattened Device Tree blob at 88000000
Booting using the fdt blob at 0x88000000
Loading Device Tree to 8ffe4000, end 8ffff956 ... OK
Starting kernel ...
I have a Pandaboard ES so the loaded file is
*/boot/dtbs/omap4-panda-es.dtb.* I decompiled the file so I can add the
UART4 MUX settings using *dtc -I dtb -O
dts omap4-panda-es.dtb > omap4-panda-es.dts* (taken from here
<https://groups.google.com/forum/#!topic/hbrobotics/u-Y5PGCpPw8>). So now
we have a *omap4-panda-es.dts* which is the complete Device Tree Overlays
that sets everything up, I just need to add the UART4 MUX settings. We have
to use the *pinctrl-single,pins* property. Here
<https://learn.adafruit.com/introduction-to-the-beaglebone-black-device-tree/device-tree-overlays> is
a really good explanation about *pinctrl-single,pins*:
The pin configuration nodes for pinctrl-single are specified as pinctrl
register offset and value pairs using pinctrl-single,pins. Only the bits
specified in pinctrl-single,function-mask are updated. For example, setting
a pin for a device could be done with: pinctrl-single,pins = <0xdc 0x118>;
Where *0xdc is the offset from the pinctrl register base address* for the
device pinctrl register, and *0x118 contains the desired value of the
pinctrl register*.
This was something I misunderstood at the beginning, I though the pinctrl
address was absolute but it's relative to the base address in the tree. In
my case for example there are a lot of
*pinmux_tfp410_pins, pinmux_dss_hdmi_pins, pinmux_i2c1_pins,* etc. All
these *pinmux_** are under a parent called ****@40*, that means that
the address specified in *pinctrl *are relative to 0x40, but this
****@40* is under another node called ****@100000 *which is inside
another node called ****@4a000000*, so the addresses inside ****@40* are
relative to the base address of the node that is the sum of all these
addresses, that is 0x4a000000 + 0x100000 + 0x40 = 0x4a100040, so 0xa100040
is the base address, all the address specified in *pinctrl* are relative to
0xa100040. So, according to Table 18-504 in the OMAP4 Technical Reference
Manual (download available here
<http://www.ti.com/lit/ug/swpu235ab/swpu235ab.pdf>) the address for the
UART4 control register that control the MUX and some other things is
0x4A10015C. The base address of *pinctrl* is 0x4a100040 so the address we
must specify in *pinctrl* is 0x11c because 0x4a100040 + 0x11c = 0x4A10015C.
All the Device Tree Overlays I found of other linux distros that support
Pandaboard have the same base address 0x4a100040 (here
<http://198.47.29.151/android-sdk/kernel-video/blobs/f76170d52786213b070893ced5f0933d7a5c6674/arch/arm/boot/dts/omap4-sdp.dts> for
example). So I added under the node ****@40 *this:
// 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 "***@4806e000" 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>;
};
I took this settings from here
<http://198.47.29.151/android-sdk/kernel-video/blobs/f76170d52786213b070893ced5f0933d7a5c6674/arch/arm/boot/dts/omap4-sdp.dts> but
just changing the 0x100 and 0 will change the settings in the register. In
my case I also had to add:
linux,phandle = <0xfff>;
phandle = <0xfff>;
I don't see this in Ubuntu for example (
https://github.com/Canonical-kernel/Ubuntu-kernel/blob/master/arch/arm/boot/dts/omap4.dtsi)
but I don't know why or what is the purpose of this phandle, all I know if
that they are used as a reference, a reference I need to put somewhere else
in the Device Tree, just make sure it is unique, it can be any 32-bit value
but must be unique inside the tree. In my case there was another node
referring UART4:
***@4806e000 {
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>;
};
So there I had to use *phandle* otherwise MUX settings won't be applied:
***@4806e000 {
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>;
};
Finally, at the end of the file there a lot of definitions, one for each
node, for example
i2c1_pins = "/ocp/***@4a000000/***@100000/***@40/pinmux_i2c1_pins";
i2c2_pins = "/ocp/***@4a000000/***@100000/***@40/pinmux_i2c2_pins";
i2c3_pins = "/ocp/***@4a000000/***@100000/***@40/pinmux_i2c3_pins";
i2c4_pins = "/ocp/***@4a000000/***@100000/***@40/pinmux_i2c4_pins";
wl12xx_gpio = "/ocp/***@4a000000/***@100000/***@40/pinmux_wl12xx_gpio";
wl12xx_pins = "/ocp/***@4a000000/***@100000/***@40/pinmux_wl12xx_pins";
twl6030_pins = "/ocp/***@4a000000/***@100000/***@40/pinmux_twl6030_pins";
They just describe where each node is located, here we can clearly see what
the base address is. So here I just added this:
uart4_pins = "/ocp/***@4a000000/***@100000/***@40/pinmux_uart4_pins";
Now we have a complete and .dts file which should get the UART4 working. We
must compile it using *dtc -O dtb -o omap4-panda-es.dtb -b O -@
omap4-panda-es.dts*, this will generate a .dtb file that will replace the
one in */boot/dtbs*, so replace it and reboot! After rebooting run
*cat /sys/kernel/debug/pinctrl/4a100040.pinmux/pinmux-functions*, it should
show something like this:
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 ]
If we see *uart4* everything is fine and it should be working! Otherwise
there is something wrong in the .dts file. We can test if the uart is
working by running for example *echo -e "AT" > /dev/ttyO3*, remember that
*/dev/ttyO3* is UART4. I hope this will be useful for someone!
--
You received this message because you are subscribed to the Google Groups "pandaboard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pandaboard+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.