[RFC] FPGA configuration as MTD using Device Tree

Ulf Samuelsson u-boot at emagii.com
Mon Sep 7 19:03:09 CEST 2020


Hi,
The FPGA support in u-boot looks a bit old-fashioned to me.
I would like to have device-tree support and would
like comments on my approach.


====================================================================
BACKGROUND
Need to support loading 2 x Cyclone-10 LP FPGAs using Passive Serial.
Raw binary files (RBF) are stored in boot flash, and
u-boot will load both FPGAs before booting the OS.
The OS should be able to update the FPGAs as well.
The FPGAs must be independently configurable.

Hardwarewise, I have an SPI bus with 4 chip selects.
SPI MOSI, SCK, CS2 and CS3 are connected to the synchronous serial bus 
of the FPGA (DATA0, DCLK, the FPGA1.nCS0 and the FPGA2.nCS0)

Intel normally connect FPGA nCS0 to ground but I connect this to the SPI 
CS. The advantage is that I can have several FPGAs which are programmed 
independent to each other.

The FPGAs require three other signals (nCONFIG, nSTATUS and CONF_DONE).
Each FPGA have their own set of those signals.
====================================================================

I have not found device-tree support for FPGAs in u-boot.
Since the FPGAs are connected to the SPI, I thought adding them as MTD 
devices would result in a nice interface.

====================================================================
Example Device tree connected to a bit-bang SPI driver supporting 
multiple chip select.

The MTD configuration supplies
* Name of the FPGA (fpga property)
* The size of the configuration data
* Sideband signals for starting and checking configuration.

&soft_mcspi {
	compatible = "mcspi-gpio";
	pinctrl-names = "default";
	pinctrl-0 = <&soft_mcspi1_pins>;
	status = "okay";
	gpio-sck  = <&gpio0 7 GPIO_ACTIVE_LOW>;
	gpio-miso = <&gpio1 8 GPIO_ACTIVE_HIGH>;
	gpio-mosi = <&gpio1 9 GPIO_ACTIVE_HIGH>;
	cs-gpios =
	   <&gpio0 12 GPIO_ACTIVE_LOW>,
	   <&gpio0 13 GPIO_ACTIVE_LOW>,
	   <&gpio0 17 GPIO_ACTIVE_LOW>,
	   <&gpio0 16 GPIO_ACTIVE_LOW>;
	num-chipselects = <4>;
	#address-cells = <1>;
	#size-cells = <0>;
	...
	sspy-fpga-cfg at 3 {	/* Intel Cyclone 10, 10CL025 */
		#address-cells = <1>;
		#size-cells = <1>;
		compatible = "intel,cyclone10";
		reg = <3>; /* Chip select 0 */
		spi-max-frequency = <1000000>;
		fpga = "spyf";
		config-size	= <718569>;
		gpio-nconfig	= <&gpio3 21 GPIO_ACTIVE_HIGH>;
		gpio-nstatus	= <&gpio3 17 GPIO_ACTIVE_HIGH>;
		gpio-conf_done	= <&gpio0 18 GPIO_ACTIVE_HIGH>;
		gpio-crc_error	= <&gpio2 18 GPIO_ACTIVE_HIGH>;
	};
};
====================================================================

With a Cyclone 10 MTD driver, is would appear in the "mtd list" command
and configuring the fpga would be done using

$ mtd write.raw spyf <ram-addr>

The driver would have to implement dummy read and erase commands.

An alternative would be to add flags which would be tested by the mtd
command which would block the read and erase if the mtd device is an 
FPGA or simply test for that in the mtd command.

What would be best?
====================================================================

The MTD driver would start configuration by toggling gpio-nconfig low
and then wait for gpio-nstatus to go high.

If OK, it would call the spi_xfer routine for the parent spi slave 
(soft-mcspi)

When the spi write returns, the FPGA MTD driver would await the 
CONF_DONE signal before returning.

====================================================================

What do you guys think of such an approach?

BR
Ulf Samuelsson





More information about the U-Boot mailing list