QSPI NOR Flash

The phyCORE-AM57x SOM can incorporate a 16MB NOR Flash, serving either as volatile or non-volatile memory. Opting for an SPI Flash can obviate the necessity of installing NAND Flash or eMMC memory on the SOM. This approach is particularly beneficial for applications demanding a compact code footprint or utilizing a small Real-Time Operating System (RTOS). The NOR device is linked to the qspi1 interface.

This guide furnishes instructions on interfacing with the NOR Flash from Linux. For additional details regarding the phyCORE-AM57x QSPI NOR memory, please refer to section 6.5 in the Hardware Manual.

Note

The standard development kit offering does not include a SOM with the NOR Flash populated and the QSPI interface is disabled by default. See the Release Notes for more information. For further support, please visit PHYTEC’s Support Portal.

Setup and Partition Information

  • Reference the following kernel diff to help you modify the default BSP, the QSPI interface must be enabled.

    Kernel Patch
    diff --git a/arch/arm/boot/dts/am5728-pcm-057-40300111i.dtsi b/arch/arm/boot/dts/am5728-pcm-057-40300111i.dtsi
    index 2fef05af1043..64cab5ac7169 100644
    --- a/arch/arm/boot/dts/am5728-pcm-057-40300111i.dtsi
    +++ b/arch/arm/boot/dts/am5728-pcm-057-40300111i.dtsi
    @@ -28,15 +28,15 @@
    };
    
    &qspi {
    -       status = "disabled";
    +       status = "okay";
    };
    
    &qspi_nor {
    -       status = "disabled";
    +       status = "okay";
    };
    
    &qspi_nor_cs0 {
    -       status = "disabled";
    +       status = "okay";
    };
    
    &i2c_rtc {
    
  • In order to apply the changes, referred to by the diff above, to your local kernel source first follow the Build the BSP guide and then reference the Modify The BSP guide.

  • Once you have a updated device tree blob, copy this to your bootable SD Card:

    Target (Linux)
    cd ~/Downloads
    cp am5728-phycore-kit-41300111i-NOR.dtb /media/<user>/rootfs/boot/
    
  • Safely remove the SD Card from your Host Machine.

  • Configure the development kit to boot from SD Card. Reference the SD Card guide for more information.

  • Insert the SD Card into the phyCORE-AM57x development kit and power it on.

  • Stop in U-Boot when prompted.

  • Enter the following in U-Boot to specify which device tree will be used during Linux bring-up:

    Target (U-Boot)
    setenv board_name undefined
    setenv fdtfile am5728-phycore-kit-41300111i-NOR.dtb
    saveenv
    boot
    

    Tip

    It is necessary to change the board_name variable to “undefined” so that U-Boot doesn’t automatically source the original device tree with QSPI disabled. For more information, see the Configuring the Bootloader guide.

  • Lets take a look at the flash memory to see what software defined partitions are available:

    Target (Linux)
    mtdinfo -a
    
    Example Output
    root@am57xx-phycore-kit:~# mtdinfo -a
    Count of MTD devices:           7
    Present MTD devices:            mtd0, mtd1, mtd2, mtd3, mtd4, mtd5, mtd6
    Sysfs interface supported:      yes
    
    mtd0
    Name:                           QSPI.SPL
    Type:                           nor
    Eraseblock size:                65536 bytes, 64.0 KiB
    Amount of eraseblocks:          4 (262144 bytes, 256.0 KiB)
    Minimum input/output unit size: 1 byte
    Sub-page size:                  1 byte
    Character device major/minor:   90:0
    Bad blocks are allowed:         false
    Device is writable:             true
    
    mtd1
    Name:                           QSPI.u-boot
    Type:                           nor
    Eraseblock size:                65536 bytes, 64.0 KiB
    Amount of eraseblocks:          16 (1048576 bytes, 1024.0 KiB)
    Minimum input/output unit size: 1 byte
    Sub-page size:                  1 byte
    Character device major/minor:   90:2
    Bad blocks are allowed:         false
    Device is writable:             true
    
    mtd2
    Name:                           QSPI.u-boot-spl-os
    Type:                           nor
    Eraseblock size:                65536 bytes, 64.0 KiB
    Amount of eraseblocks:          8 (524288 bytes, 512.0 KiB)
    Minimum input/output unit size: 1 byte
    Sub-page size:                  1 byte
    Character device major/minor:   90:4
    Bad blocks are allowed:         false
    Device is writable:             true
    
    mtd3
    Name:                           QSPI.u-boot-env
    Type:                           nor
    Eraseblock size:                65536 bytes, 64.0 KiB
    Amount of eraseblocks:          1 (65536 bytes, 64.0 KiB)
    Minimum input/output unit size: 1 byte
    Sub-page size:                  1 byte
    Character device major/minor:   90:6
    Bad blocks are allowed:         false
    Device is writable:             true
    
    mtd4
    Name:                           QSPI.u-boot-env.backup1
    Type:                           nor
    Eraseblock size:                65536 bytes, 64.0 KiB
    Amount of eraseblocks:          1 (65536 bytes, 64.0 KiB)
    Minimum input/output unit size: 1 byte
    Sub-page size:                  1 byte
    Character device major/minor:   90:8
    Bad blocks are allowed:         false
    Device is writable:             true
    
    mtd5
    Name:                           QSPI.kernel
    Type:                           nor
    Eraseblock size:                65536 bytes, 64.0 KiB
    Amount of eraseblocks:          128 (8388608 bytes, 8.0 MiB)
    Minimum input/output unit size: 1 byte
    Sub-page size:                  1 byte
    Character device major/minor:   90:10
    Bad blocks are allowed:         false
    Device is writable:             true
    
    mtd6
    Name:                           QSPI.file-system
    Type:                           nor
    Eraseblock size:                65536 bytes, 64.0 KiB
    Amount of eraseblocks:          98 (6422528 bytes, 6.1 MiB)
    Minimum input/output unit size: 1 byte
    Sub-page size:                  1 byte
    Character device major/minor:   90:12
    Bad blocks are allowed:         false
    Device is writable:             true
    

    We can see that this device tree defines 7 partitions for our NOR Flash.

Write to QSPI

  • Create a file that will fit into a partition (we are going to use the last partition, mtd6):

    Target (Linux)
    dd if=/dev/urandom of=/tmp/test.dat bs=64k count=98
    

    Note that the size of a partition is a multiple of the erase block size!

  • Write the file to the partition:

    Target (Linux)
    flashcp -v /tmp/test.dat /dev/mtd6
    
    Example Output
    root@am57xx-phycore-kit:~# dd if=/dev/urandom of=/tmp/test.dat bs=64k count=98
    98+0 records in
    98+0 records out
    root@am57xx-phycore-kit:~# flashcp -v /tmp/test.dat /dev/mtd6
    Erasing blocks: 98/98 (100%)
    Writing data: 6272k/6272k (100%)
    Verifying data: 6272k/6272k (100%)
    

Read from QSPI

  • Read back the file we just wrote:

    Target (Linux)
    dd if=/dev/mtd6 of=/tmp/qspi_read.dat bs=64k count=98
    
  • Lets compare the two files to ensure that what was read is the same as what was written:

    Target (Linux)
    md5sum /tmp/qspi_read.dat && md5sum /tmp/test.dat
    
    Example Output
    root@am57xx-phycore-kit:~# dd if=/dev/mtd6 of=/tmp/qspi_read.dat bs=64k count=98
    98+0 records in
    98+0 records out
    root@am57xx-phycore-kit:~# md5sum /tmp/qspi_read.dat && md5sum /tmp/test.dat
    dd83dcf5d8b7cbbfebdf012381e42f7a  /tmp/qspi_read.dat
    dd83dcf5d8b7cbbfebdf012381e42f7a  /tmp/test.dat
    

Reverting back to the Original Device Tree

  • Reset the board with the following:

    Target (Linux)
    reboot
    
  • Stop in U-Boot when prompted.

  • Return all environment variables to their defaults:

    Target (U-Boot)
    env default -f -a
    saveenv
    boot