When in Doubt, Check the Devicetree

 

It recently came to our attention that the SATA interface was broken in Linux for the UltraZed-EV and UltraZed-EG.  This is one of those "Wait! What? I know this worked before!" sorts of issues.  After doing some sleuthing by going back and booting OS images from older BSPs on the UltraZed-EV I confirmed that, sure enough, SATA was working in Linux up through the PetaLinux 2019.2 BSP.  Something broke after that.  Perhaps related to change in Linux kernel in PetaLinux 2020.1?  Probably, but can't say for sure.  Knowing when the SATA broke was a big help to narrow down where to look for a solution.  It occurred to me that the Xilinx ZCU102 board also has a SATA interface and uses the same Zynq UltraScale+ device as the UltraZed-EG, so installing a PetaLinux BSP for that board and booting that OS image should provide a clue.  Sure enough, the SATA interface worked in that OS image from the 2020.2 PetaLinux BSP for the ZCU102 board.

 

That's great!  Now what?

 

Start looking for what is different between the BSP for the ZCU102 and the UltraZed-EV that I have been experimenting with.  Experience tells me that issues like this are almost always devicetree related, so that was the first place I looked.  Indeed there was a device node description for the SATA in the ZCU102 devicetree that was missing from the devicetree for the UltraZed-EV.  Eureka!

 

Edit the UltraZed Devicetree

There are a few differences between the devicetree for the Xilinx ZCU102 board and what is needed for the UltraZeds in the system-bsp.dtsi devicetree file.

  • The SATA is on GT lane 3 on the ZCU102, and is on GT lane 1 on the UltraZeds
  • The devicetree variable PHY_TYPE_SATA is defined as '1' for the ZCU102, but is not defined for the UltraZeds.  This will be fixed in a future PetaLinux release, but for now we can hard-code this variable.
  • The cominit, comwake, burst, and retry parameters are all defined elsewhere in other devicetree include file files (this information is gleaned from the Vivado hardware platform by the devicetree generator (DTG)), so we don't actually need to specify them in the system-bsp.dtsi file.

 

The PetaLinux 2020.1 and 2020.2 BSPs for the UltraZeds and other Avnet SOMs and SBCs can be downloaded here.  Be sure to see Xilinx UG1144 for instructions for "installing" the BSP.  If you have already downloaded and "installed" the 2020.1 or 2020.2 PetaLinux BSP for UltraZed-EG or UltraZed-EV you can add/fix SATA in the Linux OS image by editing the
<BSP>/project-spec/meta-avnet/recipes-bsp/device-tree/files/<SOM>-<CARRIER>-<DESIGN>/system-bsp.dtsi file and add these lines to the end:

&sata {
     status = "okay";
     phy-names = "sata-phy";
     phys = <&lane1 1 1 1 125000000>;
};

 

Rebuild the Linux OS Image

For the PetaLinux 2020.2 (and later) BSP the scripts to rebuild the BSP can be found in the <BSP>/pre-built/linux/images/ folder (rebuild_common.sh and rebuild_<BSP>.sh) and can be copied to the <BSP>/ folder and executed.  For the 2020.1 BSP the steps are manual.  The scripts from the 2020.2 BSP should be able to be copied to a 2020.1 BSP, but this has not been tested.  If you try this please leave a note in the comments below to let us know if it worked or not.

$ cd <BSP>

$ petalinux-build -c avnet-image-minimal (for INITRD boot)

--or--

$ petalinux-build -c avnet-image-full (for EXT4 boot)

 

Copy the new image.ub Linux OS image file to the chosen boot media (e.g. SD card).

 

Verify the SATA is Working

Connect a SATA drive (SSD or spinning HD) to the UltraZed and boot the new Linux OS image.  Note that the UltraZed carrier boards do not supply power to the SATA drive, so an external power supply is required.

 

SATA power & data cableSATA power & data cable

Power supply with Molex LP4 connector: https://www.amazon.com/Genuine-Flypower-SPP34-12-0-5-0-2000-Adapter/dp/B01N7F2XMO/

Delkin 32GB SATA III SSD: https://www.avnet.com/shop/us/products/delkin-devices/de32fqqfc-35000-2-3074457345641627779

 

Verify the SATA device is recognized and enumerated during boot:

$ dmesg | grep ata

Linux should auto mount the SATA drive if it is already partitioned and formatted:

Run the Linux hdparm utility to test SATA reads from the drive:

$ hdparm -T /dev/sda1 (cached)

$ hdparm -t /dev/sda1 (buffered)

Test writing a 1 GB file filled with random data:

$ dd if=/dev/urandom of=/run/media/sda1/test.img bs=1M count=1000

NOTE: Your SATA read/write performance results will vary depending on drive type, storage density, etc. and may not match the results described here.

 

Stay Tuned

This fix to get SATA working again for the UltraZed SOMs in PetaLinux 2020.1 and 2020.2  will be incorporated into Avnet's meta-avnet git repository on the 2020.1 and 2020.2 branches and will be baked into future PetaLinux BSPs.  Making sure the SATA interface works will also be added to the regression tests for future UltraZed BSP releases.

 

Additional Resources

The SATA interface for Linux on Zynq UltraScale+ devices is also discussed on this Xilinx wiki page:

https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842339/SATA

Note this wiki page has a slightly different devicetree description for the SATA interface and kernel configuration changes that are not required to get SATA working on the UltraZeds.

 

A great reference all about SATA:

Storage Insights #6 - Guide to SATA (Serial ATA)