Hello,
recently I have been writing a device tree file for Pogoplug v4 and Pogoplug Mobile. However, I'm facing a strange problem with USB VBUS and Serial connection.
According to https://github.com/archlinuxarm/PKGBUILDs/blob/master/core/linux-kirkwood/archlinuxarm.patch#L3738, the GPIO (actually it's only a GPO pin) to enable USB VBUS has number 10. However, when using this pin with a voltage regulator as in all the other kirkwood devices' device tree files, I encounter a problem: As soon as the regulator is enabled, UART transmission stops. After looking into Kirkwood 88f6192 specs, I found the reason [only relevant lines shown, source: Kernel 3.13, Documentation/devicetree/bindings/pinctrl/marvell,kirkwood-pinctrl.txt]:
$this->bbcode_second_pass_code('', '* Marvell Kirkwood 88f6192
name pins functions
================================================================================
mpp5 5 gpo, nand(io7), uart0(txd), ptp(trig), sata0(act)
mpp10 10 gpo, spi(sck), uart0(txd), ptp(trig), sata1(act)')
So it turns out MPP10 is UART transmit (which can also be mapped to MPP5, but this is NAND already).
And if I disable the regulator, UART transmit works again.
According to my understanding, using a pin for two different functions should not be possible (although function switching at kernel run-time is supported), so the question is: Where does MPP10 for USB VBUS enable come from? I can't seem to find it in Cloudengines' Pogoplug kernel sources (although it's hard to find anything in there...)
VBUS is enabled in linux-kirkwood like this:
$this->bbcode_second_pass_code('', 'orion_gpio_set_valid(POGOPLUGV4_GPIO_USB_VBUS, 1);
if (gpio_request(POGOPLUGV4_GPIO_USB_VBUS, "USB VBUS") != 0 ||
gpio_direction_output(POGOPLUGV4_GPIO_USB_VBUS, 1) != 0)
pr_err("POGOPLUGV4: failed to setup USB VBUS GPIO\n");
/* some other initialization */
kirkwood_uart0_init();
')
If USB VBUS and UART0 both use MPP10, wouldn't kirkwood_uart0_init() disable USB VBUS again?
However, even when USB VBUS is disabled, the USB port seems to have enough power to run a 2.5 inch hard drive, so I seriously don't understand why it's needed at all.
And - just to provide everything that's interesting - here's the pinctrl configuration without USB VBUS regulator (note that on 6192 mpp40-mpp49 don't exist, but kernel has a minor bug with 6192 (see device tree comment), so I used 6281 instead (only has more pins, no important changes)):
$this->bbcode_second_pass_code('', '[root@pogoplug f1010000.pinctrl]# cat pinconf-groups
Pin config settings per pin group
Format: group (name): configs
0 (mpp0):current: nand(io2), available = [ gpio(io) spi(cs) ]
1 (mpp1):current: nand(io3), available = [ gpo(o) spi(mosi) ]
2 (mpp2):current: nand(io4), available = [ gpo(o) spi(sck) ]
3 (mpp3):current: nand(io5), available = [ gpo(o) spi(miso) ]
4 (mpp4):current: nand(io6), available = [ gpio(io) uart0(rxd) sata1(act) ptp(clk) ]
5 (mpp5):current: nand(io7), available = [ gpo(o) uart0(txd) ptp(trig) sata0(act) ]
6 (mpp6):current: sysrst(out), available = [ spi(mosi) ptp(trig) ]
7 (mpp7):current: gpo(o), available = [ pex(rsto) spi(cs) ptp(trig) ]
8 (mpp8):current: uart0(rts), available = [ gpio(io) twsi0(sda) uart1(rts) mii-1(rxerr) sata1(prsnt) ptp(clk) mii(col) ]
9 (mpp9):current: uart0(cts), available = [ gpio(io) twsi0(sck) uart1(cts) sata0(prsnt) ptp(evreq) mii(crs) ]
10 (mpp10):current: uart0(txd), available = [ gpo(o) spi(sck) sata1(act) ptp(trig) ]
11 (mpp11):current: uart0(rxd), available = [ gpio(io) spi(miso) ptp-1(evreq) ptp-2(trig) ptp(clk) sata0(act) ]
12 (mpp12):current: sdio(clk), available = [ gpio(io) ]
13 (mpp13):current: sdio(cmd), available = [ gpio(io) uart1(txd) ]
14 (mpp14):current: sdio(d0), available = [ gpio(io) uart1(rxd) sata1(prsnt) mii(col) ]
15 (mpp15):current: sdio(d1), available = [ gpio(io) uart0(rts) uart1(txd) sata0(act) ]
16 (mpp16):current: sdio(d2), available = [ gpio(io) uart0(cts) uart1(rxd) sata1(act) mii(crs) ]
17 (mpp17):current: sdio(d3), available = [ gpio(io) sata0(prsnt) ]
18 (mpp18):current: nand(io0), available = [ gpo(o) ]
19 (mpp19):current: nand(io1), available = [ gpo(o) ]
20 (mpp20):current: gpio(io), available = [ ts(mp0) tdm(tx0ql) ge1(txd0) audio(spdifi) sata1(act) ]
21 (mpp21):current: gpio(io), available = [ ts(mp1) tdm(rx0ql) ge1(txd1) audio(spdifo) sata0(act) ]
22 (mpp22):current: gpio(io), available = [ ts(mp2) tdm(tx2ql) ge1(txd2) audio(rmclk) sata1(prsnt) ]
23 (mpp23):current: gpio(io), available = [ ts(mp3) tdm(rx2ql) ge1(txd3) audio(bclk) sata0(prsnt) ]
24 (mpp24):current: gpio(io), available = [ ts(mp4) tdm(spi-cs0) ge1(rxd0) audio(sdo) ]
25 (mpp25):current: gpio(io), available = [ ts(mp5) tdm(spi-sck) ge1(rxd1) audio(lrclk) ]
26 (mpp26):current: gpio(io), available = [ ts(mp6) tdm(spi-miso) ge1(rxd2) audio(mclk) ]
27 (mpp27):current: gpio(io), available = [ ts(mp7) tdm(spi-mosi) ge1(rxd3) audio(sdi) ]
28 (mpp28):current: gpio(io), available = [ ts(mp8) tdm(int) ge1(col) audio(extclk) ]
29 (mpp29):current: gpio(io), available = [ ts(mp9) tdm(rst) ge1(txclk) ]
30 (mpp30):current: gpio(io), available = [ ts(mp10) tdm(pclk) ge1(rxctl) ]
31 (mpp31):current: gpio(io), available = [ ts(mp11) tdm(fs) ge1(rxclk) ]
32 (mpp32):current: gpio(io), available = [ ts(mp12) tdm(drx) ge1(txclko) ]
33 (mpp33):current: gpo(o), available = [ tdm(dtx) ge1(txctl) ]
34 (mpp34):current: gpio(io), available = [ tdm(spi-cs1) ge1(txen) sata1(act) ]
35 (mpp35):current: gpio(io), available = [ tdm(tx0ql) ge1(rxerr) sata0(act) mii(rxerr) ]
36 (mpp36):current: gpio(io), available = [ ts(mp0) tdm(spi-cs1) audio(spdifi) ]
37 (mpp37):current: gpio(io), available = [ ts(mp1) tdm(tx2ql) audio(spdifo) ]
38 (mpp38):current: gpio(io), available = [ ts(mp2) tdm(rx2ql) audio(rmclk) ]
39 (mpp39):current: gpio(io), available = [ ts(mp3) tdm(spi-cs0) audio(bclk) ]
40 (mpp40):current: gpio(io), available = [ ts(mp4) tdm(spi-sck) audio(sdo) ]
41 (mpp41):current: gpio(io), available = [ ts(mp5) tdm(spi-miso) audio(lrclk) ]
42 (mpp42):current: gpio(io), available = [ ts(mp6) tdm(spi-mosi) audio(mclk) ]
43 (mpp43):current: gpio(io), available = [ ts(mp7) tdm(int) audio(sdi) ]
44 (mpp44):current: gpio(io), available = [ ts(mp8) tdm(rst) audio(extclk) ]
45 (mpp45):current: gpio(io), available = [ ts(mp9) tdm(pclk) ]
46 (mpp46):current: gpio(io), available = [ ts(mp10) tdm(fs) ]
47 (mpp47):current: gpio(io), available = [ ts(mp11) tdm(drx) ]
48 (mpp48):current: gpio(io), available = [ ts(mp12) tdm(dtx) ]
49 (mpp49):current: gpio(io), available = [ ts(mp9) tdm(rx0ql) ptp(clk) ]
')
And finally - the device tree file for use with kernel 3.13:
$this->bbcode_second_pass_code('', '/dts-v1/;
#include "kirkwood.dtsi"
/* Since there is no kirkwood-6192.dtsi and mvebu_pinctrl would
* take an incorrect number of pinctrl modes (generic number
* ARRAY_SIZE(mv88f6xxx_mpp_modes)
* is used) resulting in 14 warnings about
* kirkwood-pinctrl f1010000.pinctrl: unknown pinctrl group x
* for x between 36 and 49 anyway, this device tree file will be
* based on 6281 since there are no major problems with this
* configuration. */
#include "kirkwood-6281.dtsi"
/ {
model = "Pogoplug v4";
compatible = "cloudengines,pogoplug-v4", "cloudengines,pogoplug-mobile", "marvell,kirkwood-88f6192", "marvell,kirkwood";
memory {
device_type = "memory";
reg = <0x00000000 0x8000000>;
};
chosen {
bootargs = "console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p1 rootdelay=10";
};
mbus {
pcie-controller {
status = "okay";
pcie@1,0 {
status = "okay";
};
};
};
ocp@f1000000 {
pinctrl: pinctrl@10000 {
pmx_usb_power_enable: pmx-usb-power-enable {
/* mpp10 is uart0 TXD. Regulator therefore doesn't seem to work correctly */
marvell,pins = "mpp10";
marvell,function = "gpo";
};
pmx_led_green: pmx-led-green {
marvell,pins = "mpp22";
marvell,function = "gpio";
};
pmx_led_red: pmx-led-red {
marvell,pins = "mpp24";
marvell,function = "gpio";
};
pmx_button_eject: pmx-button-eject {
marvell,pins = "mpp29";
marvell,function = "gpio";
};
};
spi@10600 {
status = "okay";
m25p05@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "m25p05-nonjedec";
reg = <0>;
spi-max-frequency = <20000000>;
mode = <0>;
};
};
serial@12000 {
status = "ok";
};
sata@80000 {
status = "okay";
nr-ports = <1>;
};
mvsdio@90000 {
pinctrl-0 = <&pmx_sdio>;
pinctrl-names = "default";
status = "okay";
cd-gpios = <&gpio0 27 0>;
/* No WP GPIO */
};
};
gpio-leds {
compatible = "gpio-leds";
pinctrl-names = "default";
pinctrl-0 = <&pmx_led_red &pmx_led_green>;
health {
label = "status:green:health";
gpios = <&gpio0 22 1>;
linux,default-trigger = "default-on";
};
fault {
label = "status:red:fault";
gpios = <&gpio0 24 1>;
linux,default-trigger = "none";
};
};
gpio_keys {
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
pinctrl-0 = <&pmx_button_eject>;
pinctrl-names = "default";
button@1 {
label = "Eject Button";
linux,code = <161>; /* EJECTCD */
gpios = <&gpio0 29 1>;
};
};
regulators {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
pinctrl-0 = <&pmx_usb_power_enable>;
pinctrl-names = "default";
usb_power: regulator@1 {
/* This renders UART0 unusable */
compatible = "regulator-fixed";
reg = <1>;
regulator-name = "USB Power";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
enable-active-high;
regulator-always-on;
regulator-boot-on;
gpio = <&gpio0 10 0>;
};
};
};
&nand {
status = "okay";
partition@0 {
label = "u-boot";
reg = <0x0000000 0x200000>;
read-only;
};
partition@200000 {
label = "uImage";
reg = <0x200000 0x300000>;
};
partition@500000 {
label = "uImage2";
reg = <0x500000 0x300000>;
};
partition@800000 {
label = "failsafe";
reg = <0x800000 0x800000>;
};
partition@1000000 {
label = "root";
reg = <0x1000000 0x7000000>;
};
};
&mdio {
status = "okay";
ethphy0: ethernet-phy@0 {
device_type = "ethernet-phy";
reg = <0>;
};
};
ð0 {
status = "okay";
ethernet0-port@0 {
phy-handle = <ðphy0>;
};
};
')
Does anyone have any hints on this? Anything wrong with my understanding of USB VBUS? Or has anyone a hint on where to find a reference to MPP10 in Cloudengines' sources?