This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How to access SPI flash from user space

Other Parts Discussed in Thread: OMAP-L138, OMAPL138, OMAP-L137

I have inherited a Linux software project on a custom board using OMAP-L138.

How do I read, write SPI flash from OMAP-L138 ARM Linux user space?

Note that I can read, erase, write the SPI  flash from U-boot.

u-boot sees the SPI flash as:

U-Boot > sf probe 0
16384 KiB M25P128 at 0:0 is now current device

Linux config:

root@arago:~# zcat /proc/config.gz  | grep -i SPI | grep -iv spin
# CONFIG_SCSI_SPI_ATTRS is not set
CONFIG_SPI=y
# CONFIG_SPI_DEBUG is not set
CONFIG_SPI_MASTER=y
# SPI Master Controller Drivers
CONFIG_SPI_DAVINCI=y
CONFIG_SPI_BITBANG=y
# CONFIG_SPI_GPIO is not set
# CONFIG_SPI_DESIGNWARE is not set
# SPI Protocol Masters
# CONFIG_SPI_TLE62X0 is not set
# SPI GPIO expanders:
# SPI RTC drivers

root@arago:~# dmesg  | grep -i spi
spi_davinci spi_davinci.1: DaVinci SPI driver in EDMA mode
spi_davinci spi_davinci.1: Controller at 0xfef0e000

I see no spi entries under /dev/spi* but I do see entries under /sys  :

root@arago:~# find /dev | grep -i spi
root@arago:~# ls /dev/spi*
ls: /dev/spi*: No such file or directory
root@arago:~# find /sys/ | grep -i spi
/sys/devices/platform/spi_davinci.1
/sys/devices/platform/spi_davinci.1/uevent
/sys/devices/platform/spi_davinci.1/modalias
/sys/devices/platform/spi_davinci.1/subsystem
/sys/devices/platform/spi_davinci.1/driver
/sys/devices/platform/spi_davinci.1/spi_master
/sys/devices/platform/spi_davinci.1/spi_master/spi1
/sys/devices/platform/spi_davinci.1/spi_master/spi1/uevent
/sys/devices/platform/spi_davinci.1/spi_master/spi1/subsystem
/sys/devices/platform/spi_davinci.1/spi_master/spi1/device
/sys/devices/platform/spi_davinci.1/spi1.0
/sys/devices/platform/spi_davinci.1/spi1.0/uevent
/sys/devices/platform/spi_davinci.1/spi1.0/modalias
/sys/devices/platform/spi_davinci.1/spi1.0/subsystem
/sys/bus/platform/devices/spi_davinci.1
/sys/bus/platform/drivers/spi_davinci
/sys/bus/platform/drivers/spi_davinci/spi_davinci.1
/sys/bus/platform/drivers/spi_davinci/uevent
/sys/bus/spi
/sys/bus/spi/uevent
/sys/bus/spi/devices
/sys/bus/spi/devices/spi1.0
/sys/bus/spi/drivers
/sys/bus/spi/drivers_probe
/sys/bus/spi/drivers_autoprobe
/sys/class/spi_master
/sys/class/spi_master/spi1

root@arago:~# uname -a
Linux arago 2.6.33-rc4 #2 PREEMPT Fri Jan 13 10:57:59 CST 2012 armv5tejl unknown

The board is custom, with code ported from da850 evm.

  • As far as I can tell, I have 2 choices: the mainline Linux spidev driver, and the davinci_spi driver.

    How is the davinci_spi driver used?  Does user code follow the POSIX open,read,write,ioctl paradigm?

    How do I specify the SPI flash address range of interest?

    The kernel DaVinci SPI driver said it found a controller, but I don't see any /dev/spi* device file for userspace.

    Does udev need help creating a /dev/spi* file?

    Any guidance would be appreciated.

    Jeff

  • Maybe consider using the MTD interface rather than the direct SPI interface. The OMAP-L138 EVM code has hooks in it for SPI flash. See kernel source file:

    arch/arm/mach-davinci/board-da850-evm.c

    Look for da850evm_spiflash_part for definition of the partitions. The partitiions will appear as /dev/mtd0, /dev/mtd1, etc. The partitions will also have a hard-drive-like block interface at /dev/mtdblock0, etc. If you have the NAND flash driver installed, it will also occupy some /dev/mtd entries.

    From user space, there are some flash utilities some usually come with the default filesystem, eg. flash_erase_all, flashcp, etc. A partition can be programmed by  redirecting a file into /dev/mtd. Personnally found that a bit flaky. Usually use one of the utilities. Not sure of the name, I think the name of source is flashtutils.

  • Thanks.  I would like to try the MTD interface.  However,  I have no /dev/spi* nor any /dev/mtd* device files for user space.   Which kernel configs enable these? (I would have suspected CONFIG_MTD_CHAR=y should have done it.)

    Here are my CONFIG_MTD* kernel configs:

    root@arago:~# zcat /proc/config.gz  | grep MTD
    CONFIG_MTD=y
    # CONFIG_MTD_DEBUG is not set
    # CONFIG_MTD_TESTS is not set
    # CONFIG_MTD_CONCAT is not set
    CONFIG_MTD_PARTITIONS=y
    # CONFIG_MTD_REDBOOT_PARTS is not set
    CONFIG_MTD_CMDLINE_PARTS=y
    # CONFIG_MTD_AFS_PARTS is not set
    # CONFIG_MTD_AR7_PARTS is not set
    CONFIG_MTD_CHAR=y
    CONFIG_MTD_BLKDEVS=y
    CONFIG_MTD_BLOCK=y
    # CONFIG_MTD_OOPS is not set
    # CONFIG_MTD_CFI is not set
    # CONFIG_MTD_JEDECPROBE is not set
    CONFIG_MTD_MAP_BANK_WIDTH_1=y
    CONFIG_MTD_MAP_BANK_WIDTH_2=y
    CONFIG_MTD_MAP_BANK_WIDTH_4=y
    # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
    # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
    # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
    CONFIG_MTD_CFI_I1=y
    CONFIG_MTD_CFI_I2=y
    # CONFIG_MTD_CFI_I4 is not set
    # CONFIG_MTD_CFI_I8 is not set
    # CONFIG_MTD_RAM is not set
    # CONFIG_MTD_ROM is not set
    # CONFIG_MTD_ABSENT is not set
    # CONFIG_MTD_COMPLEX_MAPPINGS is not set
    # CONFIG_MTD_PLATRAM is not set
    # Self-contained MTD device drivers
    # CONFIG_MTD_SST25L is not set
    # CONFIG_MTD_SLRAM is not set
    # CONFIG_MTD_PHRAM is not set
    # CONFIG_MTD_MTDRAM is not set
    # CONFIG_MTD_BLOCK2MTD is not set
    # CONFIG_MTD_DOC2000 is not set
    # CONFIG_MTD_DOC2001 is not set
    # CONFIG_MTD_DOC2001PLUS is not set
    # CONFIG_MTD_NAND is not set
    # CONFIG_MTD_ONENAND is not set
    # CONFIG_MTD_LPDDR is not set
    # CONFIG_MTD_UBI is not set


    Or do I need to tweak my udev config?

  • I don't think you need to mess with udev. No expert on that. I've lucked out so far in the MTD devices just "magically" appear. See the SPI section of

    http://processors.wiki.ti.com/index.php/GSG:_Building_Software_Components_for_OMAP-L1/AM1x

    Maybe you need to enable the SPI flash driver. I can't remember if board code needs are config to pull in the SPI board init code.

  • Hi Jeff, I have the exact same problem - were you successful?  I'm really hoping to find something where I can read/write regions in SPI flash

    I have a similar question from a while back - the URL is http://e2e.ti.com/support/embedded/linux/f/354/t/224107.aspx,  for the next guy :)

    thanks!

  • Hi, Chris!

    Look in this thread http://e2e.ti.com/support/embedded/linux/f/354/t/203769.aspx

    And you can try to use flash utils from busybox: flash_eraseall, flash_lock,  flash_unlock, flashcp.

  • I'm see flash_lock and flash_unlock as part of busybox but not the erase and cp commands,  is there a patch I need?

    http://www.busybox.net/downloads/BusyBox.html

  • No. This utilites was in busybox (I use version 1.20.2) without any patches. Try to set this options while configuring busybox:

    make menuconfig

    Main menu ---> Miscellaneous Utilities

    [*] flashcp

    [*] flash_eraseall 

  • Hey thanks alot! Looks like the command just didn't make the website! As for creating the devnode are you using 'mknod /dev/mtd0 c 90 0'? Thanks again!
  • Hi, Chris!

    I don't create any device nodes or partitions. It were created automatically. In linux kernel configuration I set:

    In group:

    Device Drivers

      Memory Technology Device (MTD) support

        Self-contained MTD device drivers --->

           <*> Support most SPI Flash chips (AT26DF, M25P, W25X, ...)

    May be it will be helpful for you.

  • Hi Norman,

    I am try to use MTD interface to read/write the SPI Flash on omapl138 kit. As you stated the spiflash_part is in board-da850-evm.c, it contains 6 sections and also can see from /dev/mtd_x( _x is 0~ 5). So, I assumed this /dev/mtd is point to the SPI Flash. As we knew the SPI Flash was programmed ulb, u-boot, and or other images at u-boot, however, when I read them from user space these sections are all 0xFF. I can read them back correctly if I write data from user space. 

    So, I am wonder if this MTD points to a different memory (as I knew there is no another flash memory on the experimenter kit), That is what I am confused.

    Other question is why mtd.size, mtd.erasesize, and mtd.writesize are different? for example, on /dev/mtd3

    mtd.type = MTD_NORFLASH
    mtd.flags = MTD_CAP_NORFLASH
    mtd.size = 2621440 (2M)
    mtd.erasesize = 65536 (64K)
    mtd.writesize = 1
    mtd.oobsize = 0
    regions = 0

    Also, do you know why set the writesize=1?, what is oobsize?

    Here is one more ask:

    root@arago:~# flash_info /dev/mtd3
    Device /dev/mtd3 has 0 erase regions

    Do you also know what is " 0 erase regions"?

    Thank you

    Joe



  • It's been while since I dealt with Linux. Some guesses. The board-da850-evm.c defines MTD partitions for all 3 types, SPI Flash, NOR and NAND Flash. The definitions might not be used depending on the code. In that regard, you'll have trace through the rather obtuse levels of indirection to see if the definitions get used. I vaguely remember more than one MTD can be defined. The partitions will show up in /dev/mtdN in order of instantiation. Each flash type appends onto previous MTDs. So /dev/mtd0 could be the start of SPI partitions, /dev/mtd6 could be NOR partition 0, and so on.

    Try checking /proc/mtd and /sys/class/mtd to see what actually got instantiated. You should be able to match to the partition definitions of name and size. These are what I see in 3.21 and 3.22 versions of the TI kernel.

    SPI flash
    "UBL", 64K,
    "U-Boot", 512K,
    "U-Boot-Env", 64K
    "Kernel", 2M+512K
    "Filesystem", 4M,
    "MAC-Address", 64K

    NOR flash
    "bootloaders + env", 512K,
    "kernel",  2M or 4M depending on PSP versiobn
    "filesystem",  size is remaining flash

    NAND flash
    "u-boot env", 128K,
    "UBL", 128K,
    "u-boot", 4*128K,
    "kernel", 4M,
    "filesystem", size is remaining flash

    If I remember correctly, OOB (Out Of Band) is memory used by NAND flash to hold error correction codes.

  • Hi Norman, Thank you for helping.

    I did some experiment on the this issue. 1st I use "flash_eraseall" to erase /dev/mdtN. As we can gusted the system will not boot up if this is SPI Flash, the result proves the system cannot boot up. That means the /dev/mtdN is the SPI Flash, but why I cannot read it right?

    the /proc/mtd shows following, which is same as board-da830-evm.c code.

    dev: size erasesize name
    mtd0: 00010000 00010000 "UBL"
    mtd1: 00080000 00010000 "U-Boot"
    mtd2: 00010000 00010000 "U-Boot-Env"
    mtd3: 00280000 00010000 "Kernel"
    mtd4: 00400000 00010000 "Filesystem"
    mtd5: 00010000 00010000 "MAC-Address"

    From there, I cannot find what type of Flash, So I do "cat" as you suggested.

    cat /sys/class/mtd/mtd1/type = nor

    ls /sys/class/mtd/mtd1/device/driver/ = bind spi1.0 uevent unbind

    From these two we can know, it is nor type flash (not serial flash, why?) and it uses spi1.0 as driver

    So, confuse me. No idea what is going on here.

    Joe

  • SPI flash has have some underlying memory technology, probably NAND or NOR. I suspect NOR is easiest to use with SPI communications. No ECC to deal with. The SPI flash driver must detect the underlying type.

    The MTD partition definitions of address and size in the board-da850-evm.c may not actually match the actual usage by u-boot and UBL. I've seen that sort of thing on old kernel releases for the OMAP-L137. Perhaps this is happening on the OMAP-L138. Restating the /proc/mtd as absolute address and size:

    dev   address  size     name
    mtd0: 00000000 00010000 "UBL"
    mtd1: 00010000 00080000 "U-Boot"
    mtd2: 00090000 00010000 "U-Boot-Env"
    mtd3: 000A0000 00280000 "Kernel"
    mtd4: 00320000 00400000 "Filesystem"
          00360000 00490000 unused
    mtd5: 007F0000 00010000 "MAC-Address"

    In your other posts, your u-boot assumes these locations

    address size      name
    00080000 00200000 kernel
    00280000 00400000 ramdisk

    This does not match the board.c file. No idea why all data is 0xFF. I would expect that you would eventually run into an image eventually.