QSPI Flash
snickerdoodle has one of several QSPI flash ICs. Each flash interface adheres to JEDEC-standard JESD216
Part Number | Manifacturer ID | Device ID |
---|---|---|
N25Q128A11 (obsolete) | 0x20 | 0xBB18 |
MT25QL128 | ||
IS25WP128 | 0x9D | 0x7018 |
Contents
U-Boot Driver
drivers/mtd/spi/spi_flash_ids.c
{"is25lp128", INFO(0x9d6018, 0x0, 64 * 1024, 256, RD_FULL | WR_QPP) },
...
{"n25q128a", INFO(0x20bb18, 0x0, 64 * 1024, 256, RD_FULL | WR_QPP) },
Linux Driver
As a result of standardization, various QSPI flash devices are supported by a single driver. Differences between devices are resolved by the driver with a table of device parameters. The JEDEC manufacturer and device ID are used to lookup device parameters from the table in drivers/mtd/spi-nor/spi-nor.c
.
{ "is25wp128", INFO(0x9d7018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },
...
{ "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ | USE_FSR | SPI_NOR_HAS_LOCK) },
Device Tree
&qspi { status = "okay"; is-dual = <0>; num-cs = <1>; xlnx,qspi-mode = <1>; flash@0 { #address-cells = <1>; #size-cells = <1>; compatible = "jedec,spi-nor"; reg = <0x0>; spi-max-frequency = <50000000>; m25p,fast-read; partition@fsbl-uboot { label = "fsbl-uboot"; reg = <0x0 0xe0000>; }; partition@uenv { label = "uenv"; reg = <0xe0000 0x20000>; }; partition@device-tree { label = "device-tree"; reg = <0x100000 0x20000>; }; partition@linux { label = "linux"; reg = <0x120000 0x600000>; }; partition@ramfs { label = "ramfs"; reg = <0x720000 0x4E0000>; }; partition@bitstream { label = "bitstream"; reg = <0xC00000 0x400000>; }; }; };
Updating QSPI Images
Updating with U-Boot
Updating with Linux
The QSPI flash images can be independently updated using the partition layout specified by the device tree node. Each partition is represented in the Linux system with an MTD block device.
# flashcp -v /boot/qspi/boot.bin /dev/mtd0 # flashcp -v /boot/qspi/uenv.bin /dev/mtd1 # flashcp -v /boot/qspi/devicetree.dtb.bin /dev/mtd2 # flashcp -v /boot/qspi/uImage.bin /dev/mtd3 # flashcp -v /boot/qspi/uramdisk.image.gz.bin /dev/mtd4 # flashcp -v /boot/qspi/bitstream.bin /dev/mtd5
Updating with JTAG
A U-Boot binary is used by program_flash
to perform operations on the QSPI flash. This binary must be updated to support the ISSI IS25WP128. To do this, the U-Boot binary in XSDK installation directory.
/opt/Xilinx/SDK/2017.3/data/xicom/cfgmem/uboot/zynq_qspi_x1_single.bin
$ program_flash -f boot.bin -verify -flash_type qspi_single -offset 0 -cable type xilinx_tcf url TCP:localhost:3121
--- a/drivers/mtd/spi/spi_flash_ids.c 2017-12-03 19:04:59.627859064 -0800 +++ b/drivers/mtd/spi/spi_flash_ids.c 2017-12-13 23:17:12.897569185 -0800 @@ -70,6 +70,7 @@ {"is25lp032", INFO(0x9d6016, 0x0, 64 * 1024, 64, 0) }, {"is25lp064", INFO(0x9d6017, 0x0, 64 * 1024, 128, 0) }, {"is25lp128", INFO(0x9d6018, 0x0, 64 * 1024, 256, 0) }, + {"is25wp128", INFO(0x9d7018, 0x0, 64 * 1024, 256, RD_FULL | WR_QPP) }, #endif #ifdef CONFIG_SPI_FLASH_MACRONIX /* MACRONIX */ {"mx25l2006e", INFO(0xc22012, 0x0, 64 * 1024, 4, 0) },
Build U-Boot with the QSPI configuration.
$ make ARCH=arm zynq_cse_qspi_defconfig
Set CONFIG_SYS_PROMPT to "zynq-uboot> "
$ make ARCH=arm CROSS_COMPILE=arm-none-eabi-
$ cp u-boot /opt/Xilinx/SDK/<release>/data/xicom/cfgmem/uboot/zynq_qspi_x1_single.bin
Quad mode enable for IS25WP128
WriteBuffer[0] = WRITE_ENABLE_CMD; XQspiPs_PolledTransfer(QspiInstancePtr, WriteBuffer, ReadBuffer, 1); WriteBuffer[0] = READ_STATUS_CMD; XQspiPs_PolledTransfer(QspiInstancePtr, WriteBuffer, ReadBuffer, 2); WriteBuffer[0] = WRITE_STATUS_CMD; /* non-volatile status register */ WriteBuffer[1] = ReadBuffer[1] | 0x40; /* quad enable bit */ XQspiPs_PolledTransfer(QspiInstancePtr, WriteBuffer, ReadBuffer, 2); WriteBuffer[0] = READ_STATUS_CMD; XQspiPs_PolledTransfer(QspiInstancePtr, WriteBuffer, ReadBuffer, 2);