LAN969x QSPI

1. LAN969x QSPI

1.1. SoC Resources

LAN969x supports two QSPI interfaces - QSPI0 and QSPI2.

1.2. Kernel configurations

Following kernel config options should be enabled to use LAN969x 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.

1.3. 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 to the datasheet for QSPIx [where x is QSPI index (0 or 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

75

43

qspi2

98

66

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).

  • spi-max-frequency must be set to 100Mhz.

  • assigned-clock-rates can be set up to 100Mhz.

  • 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.

1.3.1. References

1.3.2. Example

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

dtsi file:

qspi0: spi@e0804000 {
	compatible = "microchip,lan966x-qspi";
	reg = <0xe0804000 0x00000100>,
	      <0x20000000 0x08000000>;
	reg-names = "qspi_base", "qspi_mmap";
	interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
	clocks = <&fabric_clk>, <&clks GCK_ID_QSPI0>;
	clock-names = "pclk", "gclk";
	assigned-clocks = <&clks GCK_ID_QSPI0>;
	assigned-clock-rates = <100000000>;
	spi-max-frequency = <100000000>;
	#address-cells = <1>;
	#size-cells = <0>;
	status = "disabled";
};

dts file:

&qspi0 {
	status = "okay";

	spi-flash@0 {
		compatible = "jedec,spi-nor";
		reg = <0>;
		spi-max-frequency = <104000000>;
		#address-cells = <1>;
		#size-cells = <1>;
		spi-tx-bus-width = <1>;
		spi-rx-bus-width = <4>;
		m25p,fast-read;
	};
};

1.4. UserSpace

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

1.4.1. 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.

1.4.2. Example on how to use

# dmesg | grep spi
[    0.954840] atmel_spi e0060400.spi: Atmel SPI Controller using PIO only
[    0.961449] atmel_spi e0060400.spi: Using FIFO (32 data)
[    0.967421] atmel_spi e0060400.spi: Atmel SPI Controller version 0x401 at 0xe0060400 (irq 19)
[    0.976848] spi-nor spi1.0: sst26wf016b (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

Erase/Read/Write test:

# flash_erase /dev/mtd0 0 0x10
Erasing 128 Kibyte @ 1e0000 -- 100 % complete
#
#
# mtd_debug read /dev/mtd0 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 "lan969x" > wr
#
#
# mtd_debug write /dev/mtd0 0x1e0000 0x8 wr
Copied 8 bytes from wr to address 0x001e0000 in flash
#
#
# mtd_debug read /dev/mtd0 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  |lan969x.........|
00000010
#
# flash_erase /dev/mtd0 0 0x10
Erasing 128 Kibyte @ 1e0000 -- 100 % complete
# mtd_debug read /dev/mtd0 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/mtd0 0x1e0000 106 wr1
Copied 106 bytes from wr1 to address 0x001e0000 in flash
#
#
# mtd_debug read /dev/mtd0 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/mtd0 0 0x10
Erasing 128 Kibyte @ 1e0000 -- 100 % complete
# mtd_debug read /dev/mtd0 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
#