Quad SPI Controller


Introduction

The Quad-SPI flash controller is part of the input/output peripherals (IOP) located within the processing system (PS). It is used to access multi-bit serial flash memory devices for high throughput and low pin count applications. The controller operates in one of three modes: I/O mode, linear addressing mode, and legacy SPI mode.

I/O Mode:
In I/O mode, software interacts closely with the flash device protocol. The software writes the flash commands and data to the controller using the four TXD registers. Software reads the RXD register that contains the data received from the flash device.

Linear Addressing Mode:
Linear addressing mode uses a subset of device operations to eliminate the software overhead that the I/O mode requires to read the flash memory. Linear Mode engages hardware to issue commands to the flash memory and control the flow of data from the flash memory bus to the AXI interface. The controller responds to memory requests on the AXI interface as if the flash memory were a ROM memory.

Legacy Mode:
In legacy mode, QSPI controller acts as a normal SPI controller.

U-Boot Configuration

For ZynqMP

CONFIG_ZYNQMP_QSPI
CONFIG_SPI_FLASH_BAR
CONFIG_DM_SPI_FLASH
CONFIG_SPI_FLASH

For Zynq

CONFIG_ZYNQ_QSPI=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_BAR=y
 

Device Tree

For ZynqMP

&qspi {
       status = "okay";
       flash@0 {
               compatible = "m25p80"; /* Micron MT25QU512ABB8ESF */
               #address-cells = <1>;
               #size-cells = <1>;
               reg = <0x0>;
               spi-tx-bus-width = <1>;
               spi-rx-bus-width = <4>;
               spi-max-frequency = <108000000>; /* Based on DC1 spec */
               partition@qspi-fsbl-uboot { /* for testing purpose */
                       label = "qspi-fsbl-uboot";
                       reg = <0x0 0x100000>;
               };
               partition@qspi-linux { /* for testing purpose */
                       label = "qspi-linux";
                       reg = <0x100000 0x500000>;
                };
               partition@qspi-device-tree { /* for testing purpose */
                       label = "qspi-device-tree";
                       reg = <0x600000 0x20000>;
               };
               partition@qspi-rootfs { /* for testing purpose */
                       label = "qspi-rootfs";
                       reg = <0x620000 0x5E0000>;
               };
       };
};

For Zynq:

&qspi {
       status = "okay";
       is-dual = <0>;
       num-cs = <1>;
       flash@0 {
               compatible = "n25q128a11";
               reg = <0x0>;
               spi-tx-bus-width = <1>;
               spi-rx-bus-width = <4>;
               spi-max-frequency = <50000000>;
               #address-cells = <1>;
               #size-cells = <1>;
               partition@qspi-fsbl-uboot {
                       label = "qspi-fsbl-uboot";
                       reg = <0x0 0x100000>;
               };
               partition@qspi-linux {
                      label = "qspi-linux";
                       reg = <0x100000 0x500000>;
               };
               partition@qspi-device-tree {
                       label = "qspi-device-tree";
                       reg = <0x600000 0x20000>;
               };
               partition@qspi-rootfs {
                       label = "qspi-rootfs";
                       reg = <0x620000 0x5E0000>;
               };
               partition@qspi-bitstream {
                       label = "qspi-bitstream";
                       reg = <0xC00000 0x400000>;
               };
       };
};
 

Test Procedure

Zynq> sf probe
SF: Deteced s25fl064l with page size 256 Bytes, erase size 64 KiB, total 8 MiB
Zynq> sf erase 0 100000
SF: 1048576 bytes @ 0x0 Erased: OK
Zynq> mw.b 100000 ff 100000
Zynq> sf write 100000 0 100000
device 0 offset 0x0, size 0x100000
SF: 1048576 bytes @ 0x0 Written: OK
Zynq> sf read 200000 0 100000
device 0 offset 0x0, size 0x100000
SF: 1048576 bytes @ 0x0 Read: OK
Zynq> cmp.b 100000 200000 100000
Total of 1048576 byte(s) were the same
 

Features

For Zynq QSPI:

  • 32-bit AXI interface for Linear Addressing mode transfers
  • 32-bit APB interface for I/O mode transfers
  • Programmable bus protocol for flash memories from Micron and Spansion
  • Legacy SPI and scalable performance: 1x, 2x, 4x, 8x I/O widths
  • Flexible I/O
  • Single SS 4-bit I/O flash interface mode
  • Dual SS 8-bit parallel I/O flash interface mode
  • Dual SS 4-bit stacked I/O flash interface mode
  • Single SS, legacy SPI interface
  • 16 MB addressing per device (32 MB for two devices)

For ZynqMP QSPI:

  • Low-level (generic) access
  • 3, 4, 6,…n-byte addresses
  • SPI NAND flash devices
  • Command queuing (generic FIFO depth is 32)'
  • 4- or 8-bit interface
  • Two chip-selected lines
  • 4-bit bidirectional I/O signals
  • x1, x2, and x4 read/write
  • 44-bit address space on AXI in DMA mode
  • Byte stripe when two data buses are connected
  • Single interrupt for Quad-SPI/DMA interrupt status