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.

MTD on Beaglebone Black to access SPI Flash (N25Q256)

Other Parts Discussed in Thread: AM3352

I am trying to access  SPI Flash (N25Q256) from  Beaglebone Black using MTD. This is a follow-up to my earlier post Booting Beaglebone Black from SPI Flash (N25Q256) which was resolved and I was able to program SPI flash and load SPL, bootloader and kernel from SPI flash into RAM.


However I was never able to configure the kernel to detect SPI flash as MTD device so I can now only access SPI flash from U-boot prompt with sspi and sf commands.

While configuring the kernel I have set up the following options:

  • enabled MTD support
  • enabled command line partition table parsing (MTD_CMDLINE_PARTS [=y])
  • enabled Support most SPI Flash chips (AT26DF, M25P, W25X, ...) (MTD_M25P80 [=y])
  • just in case enabled CONFIG_MTD_CFI: and CONFIG_MTD_JEDECPROBE:

I set up the kernel command line for Linux network boot is as follows (mtdparts matches organisation of files on SPI flash used for booting BBB)

[    0.000000] Kernel command line: console=ttyO0,115200n8 mtdparts=m25p80-flash
.0:128k(SPL),384k(u-boot),5000k(kernel),128k(fdt),-(unused) root=/dev/nfs nfsroom
t=192.168.1.2:/opt/ti-sdk-am335x-evm-08.00.00.00/targetNFS,nolock rw ip=dhcp

To load SPI driver I modified the device tree and I can see the devices spidev1.0 and spidev1.1 following kernel boot.

However there are no sign whatsoever of the mtd driver m25p80 loading or SPI flash being detected during kernel boot. /proc/mtd is also empty.

What should I do to initialise MTD and access SPI flash? Do I also have to change a board initialisation file and specify valid mtd_partition there? If yes, what would be that file and could you guide me to a relevant example?

Regards


Eugene

  • Hi Eugene,

    I will ask the SW team to help on this.
  • Hi Euigene,

    Can you try going to
    /lib/modules/3.14.26-g2489c02/kernel/drivers/mtd/devices

    And execute insmod m25p80.ko ?

    Best Regards,
    Yordan
  • Hi Yordan

    I tried that and it failed to load the module - unfortunately I left work now (it is late night here in Australia) and do not remember what exactly Linux was complaining about. I will check this tomorrow and get back to you.

    In the meantime after thinking further about this problem - should I also modify the device tree to incorporate information about SPI flash and the compatible driver m25p80 into the device tree? At this stage the device tree only contains pinmux for SPI0 and information about SPI driver spidev, which ensures that SPI driver loads.

    Regards

    Eugene
  • Hi,

    Insmode probably complained about mismatching kernel build tag & module tag. Most likely it is because you've rebuilt only the kernel & used the old module which is in the file system.

    You can either rebuild the module (make modules) & copy the fresh build of m25p80.ko inside /lib/modules/3.14.26-g2489c02/kernel/drivers/mtd/devices and then execute insmode or modeprobe.

    Or you can try to use modprobe -f to force the command to ignore versioning.

    As for adding a spi flash node in the dts file, it is worth to try it, if the m25p80.ko file doesn't work.

    Best Regards,
    Yordan
  • Hi Yordan

    When I ran insmod m25p80.ko I got the following feedback:

    [ 35.019657] m25p80: disagrees about version of symbol module_layout
    insmod: ERROR: could not insert module m25p80.ko: Invalid module format

    After that I configured MTD_M25P80 as a module (it was configured as a statically built driver before), rebuilt kernel, ran make modules and copied m25p80.ko inside /lib/modules/3.14.26-g2489c02/kernel/drivers/mtd/devices.

    When I rebooted the kernel I could run insmod m25p80.ko successfully. However I still could not see any MTD partitions - /proc/mtd was empty, and there were no mtd devices in the /dev directory.

    I also tried to modify and rebuild the device tree to include information about my SPI flash. I changed file am335x-bone-common.dtsi in /opt/ti-sdk-am335x-evm-08.00.00.00/board-support/linux-3.14.26-g2489c02/arch/arm/boot/dts. The section which includes information about SPI flash is as follows (including spidev sections successfully enables SPI):

    &spi0 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&spi0_pins>;

    spidev@0 {
    spi-max-frequency = <24000000>;
    reg = <0>;
    compatible = "spidev";

    };

    spidev@1 {
    spi-max-frequency = <24000000>;
    reg = <1>;
    compatible = "spidev";

    };

    spi-flash@0 {
    compatible = "micron,n25q256a", "m25p80";
    spi-max-frequency = <24000000>;
    reg = <0>;
    };
    };

    However this change had no effect, I could not see any MTD partitions or devices.

    Finally I also tries to rebuild kernel with MTD_M25P80 configured as a statically built driver. That worked as when I trying to insmod m25p80.ko it failed with the message:

    [ 40.800297] Error: Driver 'm25p80' is already registered, aborting...
    insmod: ERROR: could not insert module m25p80.ko: Device or resource busy

    However I still could not see any MTD partitions or devices while trying device trees with or without the spi-flash section.

    I will look forward to your advice on this problem. What else and how should be changed - kernel config, device tree, command line, some board initialisation file? This issue is quite important for us as we may have similar problem with the target hardware.

    Regards

    Eugene
  • More information on this problem

    When I boot the kernel with the device tree which includes the spi-flash node, there are the following relevant lines in the kernel boot printout
    [ 1.145713] mtdoops: mtd device (mtddev=name/number) must be supplied
    [ 1.156039] omap2_mcspi 48030000.spi: chipselect 0 already in use
    [ 1.162437] spi_master spi1: spi_device register error /ocp/spi@48030000/spi-
    flash@0

    If I boot the kernel without the spi-flash node but still with both spidev nodes I can only see
    [ 1.145198] mtdoops: mtd device (mtddev=name/number) must be supplied

    Regards

    Eugene
  • I can report that a few days ago I managed to be able to load m25p80 driver and see all flash partitions just by modifying m335x-bone-common.dtsi in /opt/ti-sdk-am335x-evm-08.00.00.00/board-support/linux-3.14.26-g2489c02/arch/arm/boot/dts so that spi0 node is written as follows:

    &spi0 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&spi0_pins>;

    spi-flash@0 {
    compatible = "micron,n25q256a", "m25p80";
    spi-max-frequency = <24000000>;
    reg = <0>;
    #address-cells = <1>;
    #size-cells = <1>;
    partition@0 {
    label = "SPL";
    reg = <0x00000000 0x00020000>;
    };
    partition@20000 {
    label = "u-boot";
    reg = <0x00020000 0x00060000>;
    };
    partition@80000 {
    label = "kernel";
    reg = <0x00080000 0x00500000>;
    };
    partition@580000 {
    label = "dtb";
    reg = <0x00580000 0x00020000>;
    };
    partition@5a0000 {
    label = "-";
    reg = <0x005a0000 0x01a60000>;
    };
    };
    };

    Since then I had no problem accessing SPI flash, including placing jffs2 into the last partition and fully booting from SPI flash. Interestingly, I did not have to specify any information on MTD partitions in the kernel command line.

    The only problem that I am still facing is that once m25p80 driver is running (either as being built in or loaded) I cannot reboot from SPI flash. As we still need a resolution to this problem, I will put into a separate new question
  • Hi Eugene,

    I have more or less the same combination of parts and I have also been unable to reboot. Did you ever get this problem resolved? I have seen in another forum that Linux sets SPI NOR devices to use 4 byte addresses (which is true, in spi-nor.c) but U-Boot only supports the default 3 byte addresses. So the reboot is happening but U-Boot can't read from the flash to boot again.

    I've made some modifications to the m25p80.c driver based on this patch. It sends the software reboot command to the chip from a reboot notification.
    lists.openwrt.org/.../034153.html

    It's worked a couple of times for me. I'll post again if I find a reason not to trust it.
  • Hi Alex

    You can have a look at another question posted by me - https://e2e.ti.com/support/arm/sitara_arm/f/791/t/445297. This is the follow-up to the reboot problem. I stopped after having understood the cause of this problem (although I never received a confirmation form TI) as I was waiting for our target hardware.

    Thanks to your post I may now use this patch - most likely within a month from now.


    Regards


    Eigene

  • Hi Alex

    I have now tested the modified m25p80.c driver based suggested by you. It seems to work well both on BBB and on out target hardware which uses am3352.

    Regards

    Eugene