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 or CONFIG_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 to atmel,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 add cs0 and cs1 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 to spi_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"