Booting SATA with Fedora ARM on the Banana Pi R1

written on 26 April 2015

Over at the Korora Project, Chris and I have been dabbling on a side project (side projects, don't you just love them?!) to bring a low cost, and secure router initially aimed at cable/fibre users that is built on the open Fedora/Korora stack.

The hardware that we're playing with is the Banana Pi R1 router board made by LeMaker, it's a really affordable piece of kit that is designed to be the internals for a COTS router. It's essentially the same as the Banana Pi with a few extras including the BCM53125 network switch to drive the networking, onboard WiFi and an on‑board SATA port to hold a 2.5" SATA drive.

It's the latter feature that was an essential element for us in the project with respect to the "secure" aspect of this project. I'll speak more about our plans in a later post but for now SATA is important.

The project also provides us an opportunity to become more familiar with the Fedora ARM ecosystem (build environment, repositories, packages, etc) and what life in general is like on an ARM platform. Low cost, lower power and continual improvements in speed are all candy for those looking to develop stand alone appliances with reasonable grunt.

So that's the hardware and you know the software stack we're using. After getting a little familiar with the ARM boot sequence, including uboot, I was hitting problems with the kernel not being able to query the connected SATA drive that manifested as an endless stream of "low latency" kernel errors and never reaching the login prompt. In fact after spending about half an hour and a few dozen reboots to determine the left and right of arc of this problem I noticed that I couldn't even hear the drive spinning up - fortunately I was using a rotating disk because I would have easily burned through a lot more time before discovering that it wasn't getting sufficient power.

With the SATA drive not being adequately powered I was able to refine my Google search that ultimately lead me to a known bug over at the Bananian bug tracker. Bananian is the supported distribution from LeMaker and utilises FEX for it's hardware description hand over to the kernel as opposed to upstream Device Tree hardware description.

The solution was simple; pin 3 of port B needs to be an output and set high to enable the upconverter that drives power to the SATA drive. The solution would have been even simpler had Bananian aligned with upstream kernel development and supported the endorsed Device Tree instead of the FEX mechanism. What endured was an unexpected dive into the Device Tree world and translating this seemingly innocuous one-line FEX change into something that was Device Tree compatible. After a few weeks of undulating enthusiasm of searching and digesting as much of Device Tree one could find I finally arrived at a patch that would allow Fedora ARM (21 and 22 alpha) to complete boot and provide a login prompt with the SATA drive attached. Yes the drive enumerated successfully and was accessible as expected.

The patch shown below is for the Device Tree source (DTS). You will need the dtc utility to convert between the binary form (DTB) and the source form (DTS) of the existing Banana Pi description file.

--- a/arch/arm/boot/dts/sun7i-a20-bananapi.dts
+++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
@@ -647,6 +647,7 @@
            interrupts = <0x0 0x38 0x4>;
            clocks = <0xb 0x0 0x3 0x19>;
            status = "okay";
+           target-supply = <0x40>;
        };

        usb@01c1c000 {
@@ -903,7 +904,7 @@
            };

            ir0@0 {
-               allwinner,pins = "PB3", "PB4";
+               allwinner,pins =  "PB4";
                allwinner,function = "ir0";
                allwinner,drive = <0x0>;
                allwinner,pull = <0x0>;
@@ -985,6 +986,16 @@
                linux,phandle = <0x38>;
                phandle = <0x38>;
            };
+
+           sata_pwr_pin@0 {
+               allwinner,pins = "PB3";
+               allwinner,function = "gpio_out";
+               allwinner,drive = <0x0>;
+               allwinner,pull = <0x0>;
+               linux,phandle = <0x41>;
+               phandle = <0x41>;
+           };
+
        };

        timer@01c20c00 {
@@ -1363,4 +1374,19 @@
        linux,phandle = <0x33>;
        phandle = <0x33>;
    };
+
+   sata-5v {
+       compatible = "regulator-fixed";
+       pinctrl-names = "default";
+       pinctrl-0 = <0x41>;
+       regulator-name = "sata-5v";
+       regulator-min-microvolt = <0x4c4b40>;
+       regulator-max-microvolt = <0x4c4b40>;
+       regulator-boot-on;
+       enable-active-high;
+       gpio = <0x1b 0x1 0x3 0x0>;
+       linux,phandle = <0x40>;
+       phandle = <0x40>;
+   };
+
 };

There is no BPi-R1 specific DTS in the mainline kernel at the moment and I'm not sure when it will appear. Hopefully the aforementioned patch is sufficient a full hardware description pushed upstream to the kernel and I'm currently working out the best way to get the patch in front of the appropriate eyes.

So that is one of two problems solved. The last problem, preventing any serious development, is building an appropriate driver for the BCM53125 network switch. There have been two attempts since Oct 2014 and based on feedback of it's progress it's still a fair way off being accepted. That means packaging my first out of tree kernel driver, unless Chris beats me to it, or even you. If you do, then please get in touch and point me to your source RPM.