3.1.1.5. OSPI/QSPI NOR/NAND

Introduction

Octal Serial Peripheral Interface (OSPI) and Quad Serial Peripheral Interface (QSPI) are SPI modules that have x8 IO lines and x4 IO lines respectively. These controllers are mainly used to interface with Octal and Quad SPI flashes. OSPI is backward compatible with QSPI. These modules can also work in dual (x2) and single (x1) modes. OSPI and QSPI controllers on TI SoCs support memory mapped IO interface, which provide a direct interface for accessing data from the external SPI flash, thereby simplifying software requirements. These controllers work only in master mode.

SoC Family

Capability

Driver

AM62Px/J7200

OSPI NOR

drivers/spi/cadence_qspi.c

Note

Not all OSPI flashes can be supported. Users are recommended to check whether or not the OSPI flash part chosen for custom board designs meets all the criteria listed at https://e2e.ti.com/support/processors/f/791/t/946418

Driver Features

OSPI controllers supports PHY Calibration in DQS + Double Data Rate (DDR) mode for OSPI/QSPI NOR flashes in Octal configuration wherein data can be read on both edges of the clock, and non-DQS + Single Data Rate (SDR) mode for OSPI/QSPI NAND flashes in Quad and Octal configuration.

Memory mapped read support

Once the controller is configured in memory map mode, the whole flash memory is made available as a memory region at an SoC specific address. This region can be accessed using normal memcpy() (or mem-to-mem dma copy). Controller hardware will internally communicate with SPI flash over SPI bus and get the requested data. This mode provides the best throughput and is the default mode in the SDK.

Supported SPI modes

The cadence_qspi.c driver supports standard SPI mode 0 only.

DMA support

The driver uses mem-to-mem DMA copy on top of an OSPI/QSPI memory mapped port during flash read operations for maximum throughput and reduced CPU load.

The OSPI Controller does not support interfacing with non-flash SPI slaves.

Driver Configuration

Source Location

OSPI driver is at: drivers/spi/cadence_qspi.c under U-Boot source tree. This driver also supports QSPI version of the same IP.

DT Configuration

The following is an example device-tree node for an OSPI NOR device

&ospi0 {

   flash@0{
      compatible = "jedec,spi-nor";
      reg = <0x0>;
      spi-tx-bus-width = <8>;
      spi-rx-bus-width = <8>;
      spi-max-frequency = <25000000>;
      cdns,tshsl-ns = <60>;
      cdns,tsd2d-ns = <60>;
      cdns,tchsh-ns = <60>;
      cdns,tslch-ns = <60>;
      cdns,read-delay = <4>;

      partitions {
         compatible = "fixed-partitions";
         #address-cells = <1>;
         #size-cells = <1>;
         bootph-all;

         partition@0 {
            label = "ospi.tiboot3";
            reg = <0x00 0x80000>;
         };

         partition@80000 {
            label = "ospi.tispl";
            reg = <0x80000 0x200000>;
         };

         // other partitions
      };
   };
};

Flash properties:

  1. compatible: specifies the compatible string for the device, the operating system uses this string to identify and the match the driver for the device. Use ‘jedec,spi-nor’ for OSPI/QSPI NOR flashes and ‘spi-nand’ for OSPI/QSPI NAND flashes.

  2. spi-tx-bus-width and spi-rx-bus-width: specifies the bus width in bits for SPI transactions when transmitting (tx) and receiving (rx) data. Set for ‘8’ for OSPI flashes and ‘4’ for QSPI flashes.

  3. spi-max-frequency: defines the maximum frequency in Hertz at which the SPI bus can operate. Set 1/4th or 1/8th of ‘assigned-clocks’ value of ‘ospi0’ node for SDR and DDR mode respectively. If PHY Calibration is enabled, this value is ignored, and the maximum frequency is determined by the value specified in the ‘assigned-clocks’ property of ‘ospi0’ node.

  4. cdns,read-delay: specifies the delay in clock cycles between the fetch of a command and responding to that command by the flash devices. This differs with flashes, try with different read delays starting from 0 and find the minimum read-delay at which the flash driver probes correctly.

Note

The sf command is used to access SPI NOR flash, supporting read/write/erase and a few other functions. For more information on sf command in U-boot please refer to the u-boot documentation: here. And for accessing SPI NAND flash, the mtd command is used, supporting read/write/erase and bad block management.

AM62Px has a Cypress S28HS512T OSPI NOR flash and SYSFW is bundled with tiboot3.bin.

Below are two methods which can be used to flash the OSPI NOR device. For all methods, we will load the bootloaders into memory and then flash each to OSPI NOR at the respective addresses.

Flashing Images to OSPI NOR using TFTP server

In this example, we’ll use the tftp-hpa package from Ubuntu for our tftp server. Assume bootloader names are tiboot3.bin, tispl.bin, u-boot.img. Verify ethernet connection between AM62Px and host machine before proceeding.

  1. Setup TFTP server in Host machine

    # For complete instructions refer to: https://help.ubuntu.com/community/TFTP
    $ sudo apt install tftp-hpa
    $ sudo vi /etc/default/tftpd-hpa # optional to change tftp directory and other options
    $ sudo chown -R tftp /tftp # change owner/group of new directory /tftp
    $ sudo systemctl restart tftpd-hpa # restart server
    
  2. Setup U-boot environment for AM62Px

    # Boot to U-boot prompt using a working boot method
    => setenv ipaddr <ip-address-of-am62px>
    => setenv serverip <ip-address-of-tftp-server>
    => saveenv # optional to save the U-boot ENV
    
  3. Use tftp command to load the bootloaders into memory and flash to OSPI NOR

    => sf probe
    => tftp ${loadaddr} tiboot3.bin
    => sf update $loadaddr 0x0 $filesize
    => tftp ${loadaddr} tispl.bin
    => sf update $loadaddr 0x80000 $filesize
    => tftp ${loadaddr} u-boot.img
    => sf update $loadaddr 0x280000 $filesize
    
  4. Change boot mode pins to OSPI boot mode and reboot AM62Px

Flashing images to OSPI NOR using SD card

In this example, load binaries from SD card. Assume bootloader names are tiboot3.bin, tispl.bin, u-boot.img. Boot via SD card boot and stop at U-boot prompt before procceeding.

  1. Use fatload command to load the bootloaders into memory and flash to OSPI NOR

    => sf probe
    => fatload mmc 1 ${loadaddr} tiboot3.bin
    => sf update $loadaddr 0x0 $filesize
    => fatload mmc 1 ${loadaddr} tispl.bin
    => sf update $loadaddr 0x80000 $filesize
    => fatload mmc 1 ${loadaddr} u-boot.img
    => sf update $loadaddr 0x280000 $filesize
    
  2. Change boot mode pins to OSPI boot mode and reboot AM62Px

OSPI Boot Mode

Please refer to the AM62Px TRM Section 5.4 for more information.

Phy Calibration

Phy Calibration allows for higher read performance. To enable phy, the phy calibration pattern must be flashed to OSPI at the start of the last erase sector. For the Cypress S28HS512T flash, this lies at the address 0x3FC0000. The partition name should be ‘ospi.phypattern’ as the driver looks for it before PHY Calibration.

Download the binary file containing the phy pattern from here. The commands below can be used to flash the phy pattern, with the location of the pattern depending on which flash is being used:

=> sf probe
=> tftp ${loadaddr} ospi_phy_pattern
=> sf update $loadaddr 0x3fc0000 $filesize

Flash layout for OSPI NOR

+---------------------+ 0x0
|   ospi.tiboot3      |
|   (512k)            |
+---------------------+ 0x80000
|   ospi.tispl        |
|   (2m)              |
+---------------------+ 0x280000
|   ospi.u-boot       |
|   (4m)              |
+---------------------+ 0x680000
|   ospi.env          |
|   (256k)            |
+---------------------+ 0x6C0000
|   ospi.env.backup   |
|   (256k)            |
+---------------------+ 0x700000
|   padding           |
|   (1m)              |
+---------------------+ 0x800000
|   ospi.rootfs       |
|   (55m)(ubifs)      |
+---------------------+ 0x3FC0000
|   ospi.phypattern   |
|   (256k)            |
+---------------------+