LAN966x SPI
SoC Resources
LAN966X SoC have 5 FLEXCOMs(Flexible Serial Communication Controller). In order to use flexcom SPI interface, a specific flexcom should be configured in SPI mode.
Kernel configurations
Following kernel config options should be enabled to use LAN966x flexcom SPI interface:
- 
CONFIG_SPI_ATMEL- SPI driver config option.
- 
CONFIG_MTD,CONFIG_MTD_SPI_NORorCONFIG_MTD_SPI_NANDbased on NOR/NAND flash present.
Devicetree Configuration
To use Flexcom SPI interface, following configurations are required in device tree.
- 
Each of the flexcom flx0, flx1, flx2, flx3 and flx4 nodes can be configured in SPI mode ATMEL_FLEXCOM_MODE_SPIto use SPI interface.
- 
compatiblestring must be set toatmel,at91rm9200-spi.
- 
regproperty must be set with register address and length as<0x400 0x200>.
- 
GPIO pins for TXD, RXD and SCK should be configured to pinctrl-0property. Also addcs0andcs1pins, if present. List of possible pin mappings are as in below table:
| FLEXCOM Node | DT SCK node | SCK pin | DT RXD node | RXD pin | DT TXD node | TXD pin | 
|---|---|---|---|---|---|---|
| flx0 | fc0_a_sck_pins | GPIO8 | fc0_a_rxd_pins | GPIO9 | fc0_a_txd_pins | GPIO10 | 
| flx0 | fc0_b_sck_pins | GPIO24 | fc0_b_rxd_pins | GPIO25 | fc0_b_txd_pins | GPIO26 | 
| flx0 | fc0_c_sck_pins | GPIO61 | fc0_c_rxd_pins | GPIO62 | fc0_c_txd_pins | GPIO63 | 
| flx1 | fc1_a_sck_pins | GPIO11 | fc1_a_rxd_pins | GPIO12 | fc1_a_txd_pins | GPIO13 | 
| flx1 | fc1_b_sck_pins | GPIO33 | fc1_b_rxd_pins | GPIO34 | fc1_b_txd_pins | GPIO35 | 
| flx1 | fc1_c_sck_pins | GPIO46 | fc1_c_rxd_pins | GPIO47 | fc1_c_txd_pins | GPIO48 | 
| flx2 | fc2_a_sck_pins | GPIO14 | fc2_a_rxd_pins | GPIO15 | fc2_a_txd_pins | GPIO16 | 
| flx2 | fc2_b_sck_pins | GPIO43 | fc2_b_rxd_pins | GPIO44 | fc2_b_txd_pins | GPIO45 | 
| flx3 | fc3_a_sck_pins | GPIO17 | fc3_a_rxd_pins | GPIO18 | fc3_a_txd_pins | GPIO19 | 
| flx3 | fc3_b_sck_pins | GPIO51 | fc3_b_rxd_pins | GPIO52 | fc3_b_txd_pins | GPIO53 | 
| flx3 | fc3_c_sck_pins | GPIO30 | fc3_c_rxd_pins | GPIO31 | fc3_c_txd_pins | GPIO32 | 
| flx4 | fc4_a_sck_pins | GPIO20 | fc4_a_rxd_pins | GPIO21 | fc4_a_txd_pins | GPIO22 | 
| flx4 | fc4_b_sck_pins | GPIO56 | fc4_b_rxd_pins | GPIO57 | fc4_b_txd_pins | GPIO58 | 
| flx4 | fc4_c_sck_pins | GPIO64 | fc4_c_rxd_pins | GPIO65 | fc4_c_txd_pins | GPIO66 | 
- 
interruptsproperty must set with interrupt details. Interrupt number[CPU INTR] corresponding to a flexcom must be configured as defined in below table:
| FLEXCOM ID | Shared Peripheral Interrupt | CPU INTR | 
|---|---|---|
| flx0 | 80 | 48 | 
| flx1 | 81 | 49 | 
| flx2 | 82 | 50 | 
| flx3 | 83 | 51 | 
| flx4 | 84 | 52 | 
Note that Shared peripheral interrupt lines start at index ID32. So, CPU INTR must be calculated as [Shared peripheral interrupt number - 32].
- 
Input clock clocksproperty must be set to&nic_clk. Note that NIC clock(200Mhz) is clock used by AXI, AHB fabric and APB bridges which connects all th peripherals.
- 
clock-namesmust be set tospi_clk.
Example
Following example explains how a flexcom SPI should be defined in DT to use a SPI-NOR flash present on it:
&flx3 {
        atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_SPI>;
        microchip,flx-shrd-pins = <9>;
        microchip,flx-cs = <0>;
        status = "okay";
        spi0: spi@400 {
                compatible = "atmel,at91rm9200-spi";
                reg = <0x400 0x200>;
                interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
                clocks = <&nic_clk>;
                clock-names = "spi_clk";
                pinctrl-0 = <&fc3_b_sck_pins>, <&fc3_b_rxd_pins>, <&fc3_b_txd_pins>,
			    <&fc_shrd9_pins>;
                pinctrl-names = "default";
                dmas = <&dma0 AT91_XDMAC_DT_PERID(8)>,
                       <&dma0 AT91_XDMAC_DT_PERID(9)>;
                dma-names = "rx", "tx";
                atmel,use-dma-rx;
                atmel,use-dma-tx;
                atmel,fifo-size = <32>;
                status = "okay";
                flash: flash@0 {
                        compatible = "jedec,spi-nor";
                        reg = <0>;
                        spi-max-frequency = <104000000>;
                };
        };
};
Following example explains how to use SPI from linux userspace with spidev:
- 
Enable CONFIG_SPI_SPIDEVkernel configuration.
&flx3 {
        atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_SPI>;
        microchip,flx-shrd-pins = <9>;
        microchip,flx-cs = <0>;
        status = "okay";
        spi0: spi@400 {
                compatible = "atmel,at91rm9200-spi";
                reg = <0x400 0x200>;
                interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
                clocks = <&nic_clk>;
                clock-names = "spi_clk";
                pinctrl-0 = <&fc3_b_sck_pins>, <&fc3_b_rxd_pins>, <&fc3_b_txd_pins>,
			    <&fc_shrd9_pins>;
                pinctrl-names = "default";
                dmas = <&dma0 AT91_XDMAC_DT_PERID(8)>,
                       <&dma0 AT91_XDMAC_DT_PERID(9)>;
                dma-names = "rx", "tx";
                atmel,use-dma-rx;
                atmel,use-dma-tx;
                atmel,fifo-size = <32>;
                status = "okay";
                spi@0 {
                        compatible = "spidev";
                        reg = <0>;
                        spi-max-frequency = <50000000>;
                };
        };
};
UserSpace
MTD utility in buildroot provides rich set of tests for validating SPI NOR/NAND flashes.
Confirm instances are created
To confirm if spi flash is created:
- 
Check if a mtd device is created in /devdirectory.
- 
Run mtd_debug info /dev/mtd0command to check flash details.
To confirm if spidev device is created:
- 
Check if spidevdevice is created in/devdirectory as/dev/spidev0.0.
# ls -l /dev/spi* crw------- 1 root root 153, 0 Jan 1 00:00 /dev/spidev0.0
Example on how to use
# dmesg | grep spi [ 4.678015] atmel_spi e0064400.spi: Using dma0chan0 (tx) and dma0chan1 (rx) for DMA transfers [ 4.686861] atmel_spi e0064400.spi: Using FIFO (32 data) [ 4.703046] spi-nor spi0.0: sst26vf016b (2048 Kbytes) # mtd_debug info /dev/mtd0 mtd.type = MTD_NORFLASH mtd.flags = MTD_CAP_NORFLASH mtd.size = 2097152 (2M) mtd.erasesize = 4096 (4K) mtd.writesize = 1 mtd.oobsize = 0 regions = 0
Block erase/read/write test:
# mtd_debug erase /dev/mtd0 0 65536 Erased 65536 bytes from address 0x00000000 in flash # mtd_debug read /dev/mtd0 0 65536 read # Copied 65536 bytes from address 0x00000000 in flash to read # # dd if=/dev/urandom of=64k bs=64k count=1 1+0 records in 1+0 records out # # mtd_debug write /dev/mtd0 0 65536 64k Copied 65536 bytes from 64k to address 0x00000000 in flash # # mtd_debug read /dev/mtd0 0 65536 read Copied 65536 bytes from address 0x00000000 in flash to read # # sha1sum read 64k a3e850ee411aeec2a47c409d866a33a49771a76e read a3e850ee411aeec2a47c409d866a33a49771a76e 64k
Command to list all the available mtd devices:
# cat /proc/mtd dev: size erasesize name mtd0: 00200000 00001000 "spi0.0"