Xilinx QSPI Driver Kernel Configuration:


Drivers can be found at /drivers/spi/spi-zynqmp-gqspi.c


The following config options need to be enabled:
config SPI_ZYNQMP_GQSPI
    tristate "Xilinx ZynqMP GQSPI controller"
    depends on SPI_MASTER && HAS_DMA
    help
      Enables Xilinx GQSPI controller driver for Zynq UltraScale+ MPSoC.
 
For MTD tests
config MTD_TESTS
    tristate "MTD tests support (DANGEROUS)"
    depends on m
    help
      This option includes various MTD tests into compilation. The tests
      should normally be compiled as kernel modules. The modules perform
          various checks and verifications when loaded.


GQSPI Controller Features:

The GQSPI controller used in Zynqmp supports the following features.
  • Support Low level (Generic) Access
  • Support Future Commands
  • Supports 3,4,6…N byte addressing
  • Supports Command Queuing (Generic FIFO depth is 32)
  • Supports 4 or 8-bit interface
  • Supports 2 Chip Select Lines
  • Supports 4-Bit Bi-Directional I/O signals
  • Supports x1/x2/x4 Read/Write
  • Supports 44-bit address space on AXI in DMA mode
  • Supports byte stripe when two data buses are connected
  • Supports single interrupt for QSPI/DMA Interrupt status


Linux Driver Features:


The Zynqmp GQSPI supports the following features:

  • Supports DMA for receiving the aligned data from the tx fifo.
  • Supports PIO read for receiving the unaligned data from the rx fifo.
  • Supports PIO write from programing page to the flash.
  • Supports extended addressing.
  • Supports SIngle,Dual Parallel and Dual Stacked configurations.
  • Supports Normal and Quad read modes

Testing :

  • Device Tree node

    qspi: spi@ff0f0000 {
            compatible = "xlnx,zynqmp-qspi-1.0";
            clock-names = "ref_clk", "pclk";
            clocks = <&misc_clk &misc_clk>;
            interrupts = <0 15 4>;
            interrupt-parent = <&gic>;
            num-cs = <1>;
            reg = <0x0 0xff0f0000 0x1000>,<0x0 0xc0000000 0x8000000>;
    };

    Sample Flash node
    &qspi {
       status = "okay";
       is-dual = <0>;
       num-cs = <1>;
       flash@0 {
       compatible = "n25q512a";
       reg = <0x0>;
       spi-tx-bus-width = <1>;
       spi-rx-bus-width = <4>;
       spi-max-frequency = <10000000>;
       #address-cells = <1>;
       #size-cells = <1>;
       partition@qspi-fsbl-uboot {
          label = "qspi-fsbl-uboot";
          reg = <0x0 0x100000>;
       };
    };
  • Using Flashcp command and mtd speed test utility
root@Xilinx-ZCU102-2016_1:~# dd if=/dev/urandom of=test.bin bs=1024 count=102
<# dd if=/dev/urandom of=test.bin bs=1024 count=1024                         
1024+0 records in
1024+0 records out
root@Xilinx-ZCU102-2016_1:~#
root@Xilinx-ZCU102-2016_1:~#flashcp -v test.bin /dev/mtd0
Erasing blocks: 0/256 (0%)
Erasing blocks: 4/256 (1%)
Erasing blocks: 5/256 (1%)
Erasing blocks: 6/256 (2%)
Erasing blocks: 7/256 (2%)
Erasing blocks: 8/256 (3%)
Erasing blocks: 9/256 (3%)
-------
Erasing blocks: 256/256 (100%)
Erasing blocks: 256/256 (100%)
 
Writing data: 0k/1024k (0%)
Writing data: 10k/1024k (0%)
Writing data: 20k/1024k (1%)
---
Writing data: 1020k/1024k (99%)
Writing data: 1024k/1024k (100%)
Writing data: 1024k/1024k (100%)
 
Verifying data: 0k/1024k (0%)
Verifying data: 10k/1024k (0%)
Verifying data: 20k/1024k (1%)
---
Verifying data: 1020k/1024k (99%)
Verifying data: 1024k/1024k (100%)
Verifying data: 1024k/1024k (100%)
 
**__MTD Speed test__**
root@Xilinx-ZCU102-2016_1:~#
root@Xilinx-ZCU102-2016_1:~# insmod /lib/modules/4.4.0+/kernel/drivers/spi/mtd/tests/mtd_speedtest.ko dev=2
 
[  261.297372]
[  261.298795] =================================================
[  261.304512] mtd_speedtest: MTD device: 2
[  261.308414] mtd_speedtest: not NAND flash, assume page size is 512 bytes.
[  261.315185] mtd_speedtest: MTD device size 131072, eraseblock size 4096, page size 512, count of eraseblocks 32, pages per eraseblock 8, OOB size 0
[  261.454323] mtd_speedtest: testing eraseblock write speed
[  261.581574] mtd_speedtest: eraseblock write speed is 1057 KiB/s
[  261.587410] mtd_speedtest: testing eraseblock read speed
[  261.601605] mtd_speedtest: eraseblock read speed is 16000 KiB/s
[  262.821979] mtd_speedtest: testing page write speed
[  262.949098] mtd_speedtest: page write speed is 1049 KiB/s
[  262.954411] mtd_speedtest: testing page read speed
[  262.981224] mtd_speedtest: page read speed is 5818 KiB/s
[  264.200981] mtd_speedtest: testing 2 page write speed
[  264.328393] mtd_speedtest: 2 page write speed is 1049 KiB/s
[  264.333881] mtd_speedtest: testing 2 page read speed
[  264.353385] mtd_speedtest: 2 page read speed is 9142 KiB/s
[  264.358784] mtd_speedtest: Testing erase speed
[  265.581894] mtd_speedtest: erase speed is 105 KiB/s
[  265.586683] mtd_speedtest: Testing 2x multi-block erase speed
[  265.719973] mtd_speedtest: 2x multi-block erase speed is 1007 KiB/s
[  265.726154] mtd_speedtest: Testing 4x multi-block erase speed
[  265.859429] mtd_speedtest: 4x multi-block erase speed is 1007 KiB/s
[  265.865614] mtd_speedtest: Testing 8x multi-block erase speed
[  265.998655] mtd_speedtest: 8x multi-block erase speed is 1007 KiB/s
[  266.004832] mtd_speedtest: Testing 16x multi-block erase speed
[  266.139297] mtd_speedtest: 16x multi-block erase speed is 1000 KiB/s
[  266.145563] mtd_speedtest: Testing 32x multi-block erase speed
[  266.278941] mtd_speedtest: 32x multi-block erase speed is 1007 KiB/s
[  266.285206] mtd_speedtest: Testing 64x multi-block erase speed
[  266.418343] mtd_speedtest: 64x multi-block erase speed is 1007 KiB/s
[  266.424616] mtd_speedtest: finished
[  266.428086] =================================================
root@Xilinx-ZCU102-2016_1:~#
 

Log after driver probe:
root@Xilinx-ZCU102-2016_1:~#
root@Xilinx-ZCU102-2016_1:~#
root@Xilinx-ZCU102-2016_1:~# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00100000 00001000 "qspi-fsbl-uboot"
mtd1: 00500000 00001000 "qspi-linux"
mtd2: 00020000 00001000 "qspi-device-tree"
mtd3: 005e0000 00001000 "qspi-rootfs"
root@Xilinx-ZCU102-2016_1:~#
root@Xilinx-ZCU102-2016_1:~# dmesg | grep "spi"
[    2.947332] m25p80 spi0.0: found n25q512a, expected m25p80
[    2.952738] [spi_nor_scan]: read_opcode = 0x3b
[    2.957158] [spi_nor_scan]: program_opcode = 0x2
[    2.961807] [spi_nor_scan]: addr_width=4
[    2.965668] [spi_nor_scan]: read_dummy = 8
[    2.969746] m25p80 spi0.0: n25q512a (65536 Kbytes)
[    2.974532] 4 ofpart partitions found on MTD device spi0.0
[    2.979986] Creating 4 MTD partitions on "spi0.0":
[    2.984763] 0x000000000000-0x000000100000 : "qspi-fsbl-uboot"
[    2.991031] 0x000000100000-0x000000600000 : "qspi-linux"
[    2.996731] 0x000000600000-0x000000620000 : "qspi-device-tree"
[    3.002990] 0x000000620000-0x000000c00000 : "qspi-rootfs"
root@Xilinx-ZCU102-2016_1:~#

Changelog

2016.3
  • Added tapdelay support for higher speeds
  • Add support for 44-bit address space