LAN966x SPI
SoC Resources
LAN966X SoC have 5 FLEXCOMs (Flexible Serial Communication Controller). In order to use the Flexcom SPI interface, a specific flexcom instance must 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 the flexcom2 instance is configured as a SPI controller SPI via a device tree. The spi0 node in the controller node creates a character device that can be use to read/write to a device on the SPI bus.
In the example the GPIOs 43, 44 and 45 are used as spi clock, MISO and MOSI signals and the GPIO 51 drives the chip select signal.
You will need to connect these GPIOs to the device that must be controlled.
flx2: flexcom@e0060000 { compatible = "atmel,sama5d2-flexcom"; reg = <0xe0060000 0x100>; clocks = <&clks GCK_ID_FLEXCOM2>; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0xe0060000 0x800>; status = "disabled"; spi2: spi@400 { compatible = "atmel,at91rm9200-spi"; reg = <0x400 0x200>; interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>; dmas = <&dma0 AT91_XDMAC_DT_PERID(7)>, <&dma0 AT91_XDMAC_DT_PERID(6)>; dma-names = "tx", "rx"; clocks = <&nic_clk>; clock-names = "spi_clk"; atmel,fifo-size = <32>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; }; }; &gpio { fc2_spi_pins: fc2-spi-pins { /* SPI - SCLK, MISO, MOSI */ pins = "GPIO_43", "GPIO_44", "GPIO_45"; function = "fc2_b"; }; }; &flx2 { atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_SPI>; status = "okay"; spi2: spi@400 { pinctrl-0 = <&fc2_spi_pins>; pinctrl-names = "default"; cs-gpios = <&gpio 51 GPIO_ACTIVE_LOW>; status = "okay"; spi@0 { compatible = "spidev"; reg = <0>; spi-max-frequency = <1000000>; }; }; };
Following example explains how to use SPI from linux userspace with spidev
:
-
Enable
CONFIG_SPI_SPIDEV
kernel configuration.
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"