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_NOR
orCONFIG_MTD_SPI_NAND
based 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_SPI
to use SPI interface. -
compatible
string must be set toatmel,at91rm9200-spi
. -
reg
property must be set with register address and length as<0x400 0x200>
. -
GPIO pins for TXD, RXD and SCK should be configured to
pinctrl-0
property. Also addcs0
andcs1
pins, 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 |
-
interrupts
property 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
clocks
property 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-names
must 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_SPIDEV
kernel 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
/dev
directory. -
Run
mtd_debug info /dev/mtd0
command to check flash details.
To confirm if spidev device is created:
-
Check if
spidev
device is created in/dev
directory 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"