LAN966x QSPI

SoC Resources

LAN966x supports three QSPI interfaces - QSPI0, QSPI1 and QSPI2.

Kernel configurations

Following kernel config options should be enabled to use LAN966x QSPI interface:

  • CONFIG_SPI_ATMEL_QUADSPI - QSPI driver config option.

  • CONFIG_MTD, CONFIG_MTD_SPI_NOR or CONFIG_MTD_SPI_NAND based on NOR/NAND flash present.

Devicetree Configuration

To use QSPI interface, following configurations are required in device tree.

  • compatible string must be set to microchip,lan966x-qspi.

  • reg property must be set with base register address, AHB register address and their lengths.

  • reg-names must be set to qspi_base and qspi_mmap.

  • pinctrl-0 property must be set with SCK, NCS, IO0, IO1, IO2, IO3 GPIO pins. Refer datasheet for QSPIx [where x is QSPI index (0-2)] pin details.

  • interrupts property must set with interrupt details. Interrupt number[CPU INTR] corresponding to QSPI index must be configured as defined in below table:

QSPI ID Shared Peripheral Interrupt CPU INTR

qspi0

77

45

qspi1

97

65

qspi2

100

68

Note

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 GCK clock using phandle and GCK ID as <&clk GCK_ID_QSPIx>, where x is QSPI index (0-2).

  • clock-names must be set to pclk and gclk

  • assigned-clocks must be set to <&clks GCK_ID_QSPIx>, where x is QSPI index (0-2).

  • assigned-clock-rates must be set to 20Mhz.

  • dmas must be set to phandle dma0 and Peripheral ID as listed below:

QSPI ID Rx channel PerID Tx channel PerID

qspi0

0

1

qspi1

15

16

qspi2

17

18

For example, dmas should be configured as <&dma0 AT91_XDMAC_DT_PERID(17)> for Rx channel and <&dma0 AT91_XDMAC_DT_PERID(18)> for Tx channel. * dma-names must be set to rx and tx respectively.

Note

dmas and dma-names are optional properties.

Example

Following example shows how a QSPI should be defined in DT to use a SPI-NAND flash present on it:

dtsi file:

qspi2: spi@e0834000 {
        compatible = "microchip,lan966x-qspi";
        reg = <QSPI_2_QSPI_REGS_ADDR QSPI_2_QSPI_REGS_SIZE>,
              <0x30000000 0x04000000>;
        reg-names = "qspi_base", "qspi_mmap";
        interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
        clocks = <&clks GCK_ID_QSPI2>, <&clks GCK_ID_QSPI2>;
        clock-names = "pclk", "gclk";
        assigned-clocks = <&clks GCK_ID_QSPI2>;
        assigned-clock-rates = <20000000>;
        dmas = <&dma0 AT91_XDMAC_DT_PERID(17)>,
               <&dma0 AT91_XDMAC_DT_PERID(18)>;
        dma-names = "rx", "tx";
        #address-cells = <1>;
        #size-cells = <0>;
        status = "disabled";
};

dts file:

&qspi2 {
        pinctrl-0 = <&qspi2_pins>;
        pinctrl-names = "default";
        status = "okay";

        spi-flash@0 {
                compatible = "spi-nand";
                reg = <0>;
                spi-max-frequency = <20000000>;
                #address-cells = <1>;
                #size-cells = <1>;
                spi-tx-bus-width = <4>;
                spi-rx-bus-width = <4>;
        };
};

UserSpace

MTD utility in buildroot provides rich set of tests for validating QSPI NOR/NAND flashes.

Confirm instances are created

To confirm if qspi flash is created:

  • Check if a mtd device is created in /dev directory.

  • Run mtd_debug info /dev/mtdx (where x is index of mtd device) command to check flash details.

Example on how to use

# dmesg | grep spi
[    1.258369] atmel_qspi e0834000.spi: Using dma0chan1 (tx) and dma0chan0 (rx) for DMA transfers
[    1.284563] spi-nand spi1.0: Winbond SPI NAND was found.
[    1.289435] spi-nand spi1.0: 128 MiB, block size: 128 KiB, page size: 2048, OOB size: 64

# mtd_debug info /dev/mtd1
mtd.type = MTD_NANDFLASH
mtd.flags = MTD_CAP_NANDFLASH
mtd.size = 134217728 (128M)
mtd.erasesize = 131072 (128K)
mtd.writesize = 2048 (2K)
mtd.oobsize = 64
regions = 0

Erase/Read/Write test:

# flash_erase /dev/mtd1 0 0x10
Erasing 128 Kibyte @ 1e0000 -- 100 % complete
#
#
# mtd_debug read /dev/mtd1 0x1e0000 0x10 rd
Copied 16 bytes from address 0x001e0000 in flash to rd
# hexdump rd -C
00000000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000010
# echo "lan966x" > wr
#
#
# mtd_debug write /dev/mtd1 0x1e0000 0x8 wr
Copied 8 bytes from wr to address 0x001e0000 in flash
#
#
# mtd_debug read /dev/mtd1 0x1e0000 0x10 rd
Copied 16 bytes from address 0x001e0000 in flash to rd
#
#
# hexdump rd -C
00000000  6c 61 6e 39 36 36 78 0a  ff ff ff ff ff ff ff ff  |lan966x.........|
00000010
#
# flash_erase /dev/mtd1 0 0x10
Erasing 128 Kibyte @ 1e0000 -- 100 % complete
# mtd_debug read /dev/mtd1 0x1e0000 0x10 rd
Copied 16 bytes from address 0x001e0000 in flash to rd
#
#
# hexdump rd -C
00000000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000010
#

# echo "The W25N01GV (1G-bit) Serial SLC NAND Flash Memory provides a storage so
lution for system with lmtd space" > wr1
# ls -l wr1
-rw-r--r--    1 root     root           106 Jan  1 00:17 wr1
#
# mtd_debug write /dev/mtd1 0x1e0000 106 wr1
Copied 106 bytes from wr1 to address 0x001e0000 in flash
#
#
# mtd_debug read /dev/mtd1 0x1e0000 106 rd
Copied 106 bytes from address 0x001e0000 in flash to rd
# hexdump rd -C
00000000  54 68 65 20 57 32 35 4e  30 31 47 56 20 28 31 47  |The W25N01GV (1G|
00000010  2d 62 69 74 29 20 53 65  72 69 61 6c 20 53 4c 43  |-bit) Serial SLC|
00000020  20 4e 41 4e 44 20 46 6c  61 73 68 20 4d 65 6d 6f  | NAND Flash Memo|
00000030  72 79 20 70 72 6f 76 69  64 65 73 20 61 20 73 74  |ry provides a st|
00000040  6f 72 61 67 65 20 73 6f  6c 75 74 69 6f 6e 20 66  |orage solution f|
00000050  6f 72 20 73 79 73 74 65  6d 20 77 69 74 68 20 6c  |or system with l|
00000060  6d 74 64 20 73 70 61 63  65 0a                    |mtd space.|
0000006a
#
# flash_erase /dev/mtd1 0 0x10
Erasing 128 Kibyte @ 1e0000 -- 100 % complete
# mtd_debug read /dev/mtd1 0x1e0000 0x106 rd
Copied 262 bytes from address 0x001e0000 in flash to rd
# hexdump rd -C
00000000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000100
#