OSPI Linux driver


The Octal-SPI Flash Controller can be used to provide access to Serial Flash devices. Standard Serial Peripheral Interface (SPI) is supported along with high performance Octal SPI variants. The Octal-SPI Flash Controller transfer the data either in a memory mapped direct fashion or in an indirect fashion where the controller is set up via configuration registers to silently perform some requested operation, signalling its completion via interrupts or status registers. For indirect operations, data is transferred between system memory and external FLASH memory via an internal SRAM. OSPI has it’s own internal DMA which is used to read the data from the flash, SRAM is accessible only in case of DMA mode of operation (indirect mode).

In INDAC (Indirect Access Controller) mode DMA writes are not supported, Non-DMA, DAC or STIG modes are used for flash writes. In INDAC(DMA) mode only flash reads are supported.

Features Supported in HW

  1. Direct mode of memory mapped operation.
  2. Software triggered IO mode (STIG) up to 8-bytes of data transfers.
  3. Indirect DMA reads.
  4. NON-DMA read and write support
  5. Local SRAM to reduce AHB overhead.
  6. Supports SDR and DDR protocols.
  7. Programmable master mode clock frequencies.
  8. Serial clock with programmable polarity.
  9. Programmable peripheral selects (chip select).
  10. Support for Single and Octal instructions.
  11. Interrupts and polled based operations.

Features supported in driver

  1. Software triggered IO mode (STIG) up to 8-bytes of data transfers.
  2. INDAC DMA reads.
  3. SDR and DDR mode support.
  4. Support for Octal mode.
  5. Interrupt based transfers.
  6. RX Tuning support for PHY modes.
  7. NON-DMA read and write support.

Driver Missing features, Known Issues and Limitations

  • STIG Memory Bank.

Important AR links

  • 2023.1 Versal: OSPI flash probe fails with BSP images on VCK190 in Linux AR Link

Supported Flash parts

  • Micron
  • ISSI
  • Gigadevice
  • Macronix (works only up to 150MHz)


  • Flashcp
  • mtd utilities.
  • mtd_speedtest
  • mtd_stresstest
  • File System testing - UBIFS and JFFS2

Kernel Configuration



Sample Device-tree node for OSPI 

spi@f1010000 {
                        compatible = "xlnx,versal-ospi-1.0", "cadence,qspi", "cdns,qspi-nor";
                        status = "okay";
                        reg = <0x0 0xf1010000 0x0 0x10000 0x0 0xc0000000 0x0 0x20000000>;
                        interrupts = <0x0 0x7c 0x4 0x0 0x7c 0x4>;
                        clock-names = "ref_clk", "pclk";
                        cdns,fifo-depth = <0x100>;
                        cdns,fifo-width = <0x4>;
                        cdns,is-dma = <0x1>;
                        cdns,is-stig-pgm = <0x1>;
                        cdns,trigger-address = <0xc0000000>;
                        #stream-id-cells = <0x1>;
                        #address-cells = <0x1>;
                        #size-cells = <0x0>;
                        clocks = <0x3 0x3a 0x3 0x52>;
                        power-domains = <0x7 0x1822402a>;
                        bus-num = <0x2>;
                        num-cs = <0x1>;
                        reset-gpios = <0x28 0xc 0x0>;
                        phandle = <0x33>;

                        flash@0 {
                                compatible = "mt35xu02g", "micron,m25p80", "spi-flash";
                                reg = <0x0>;
                                #address-cells = <0x1>;
                                #size-cells = <0x1>;
                                cdns,read-delay = <0x0>;
                                cdns,tshsl-ns = <0x0>;
                                cdns,tsd2d-ns = <0x0>;
                                cdns,tchsh-ns = <0x1>;
                                cdns,tslch-ns = <0x1>;
                                spi-tx-bus-width = <0x1>;
                                spi-rx-bus-width = <0x8>;
                                spi-max-frequency = <0x1312d00>;
                                partition@0 {
                                        label = "spi0-flash0";
                                        reg = <0x0 0x10000000>;

Performance Details

At frequency 133.33 MHz

DDR mode:

Read Speed: 226768 KiB/s

Write Speed: 1696 KiB/s

Mainline Status

Features added to mainline

  • SDR NON-PHY mode
  • DMA support
  • Flash Device Reset

Not in Mainline

  • DDR mode support
  • Rx tuning
  • Stacked mode support
  • Support for ISSI, Gigadevice and Macronix.

Change Log


  • 1c82238 - Store GPIO info for resetting device during resume
  • 42f7d1c - Add support for MX66UM2G45G Macronix flash part
  • 4cce023 - Fix RX tuning failure for OSPI flashes connected in stacked mode
  • 1c6af10 - Disable 16bit SR operation for gd25lx256e flash
  • 016ecd9 - Fix call trace during suspend/resume
  • 0182633 - Remove dependency on SRAM Fill Register during indirect non-dma read


  • None


  • ae655c5 - Replace all spi->chip_select and spi->cs_gpiod references with function call
  • 8880c61 - Ads stacked memories support as per the new DT bindings
  • adc1e5f - Fix race condition while scheduling periodic tuning


  • c59a288 - Add module param to configure read timeout


  • 583238d - set cqspi to the driver_data field of struct device
  • ae78bf6 - Fix ospi resume failures


  • 7737141 - fix linking failure for ARCH arm
  • 5249597 - Limit RX max tap to 127


  • b832b6b - Added support for OSPI Macronix(mx25um51345g) part .
  • 7216a02 - Added support for reading from unaligned address.
  • 5ca8ce8 - Rx periodic tuning updates for Master DLL mode.


  • 6ab15b2 - Added support for stacked mode.
  • 3ff8d4e, 46fe093 - Added support for ISSI and GIGADEVICE parts.
  • 56e44ec - Fix the issues in Rx periodic tuning.


  • 508f0df, e0d688d - Added support for UBIFS and JFFS2 file system support.
  • 40ede36 - Added support for NON-DMA read and write support.
  • f73c158 - Added support for RX periodic tuning (periodicity of 5 minutes). 


  • New driver

© Copyright 2019 - 2022 Xilinx Inc. Privacy Policy