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.

NAND read speeds on Linux 2.6.37

Guru 10685 points

Hello,

it is now linux-2.6.37-psp04.00.00.10 and I have been trying out TI's NAND driver from Linux. I have a DM8168 EVM with the latest EZSDK. I run the following command in Linux:

dd if=/dev/mtd7ro of=/dev/null bs=1M count=100

and sadly only get 4MB/s out of it. In U-Boot it is only 2MB/s!!! i.e. it takes 25 seconds to read 100MB of data from the NAND.

I need to be able to speed this up! Reading the EVM NAND chip datasheet, apparently in 16 bit bus mode we should get 40MB/s, that's 10 times faster.

I have looked at the source code and found this structure:

enum nand_io {
    NAND_OMAP_PREFETCH_POLLED = 0,    /* prefetch polled mode, default */
    NAND_OMAP_POLLED,        /* polled mode, without prefetch */
    NAND_OMAP_PREFETCH_DMA,        /* prefetch enabled sDMA mode */
    NAND_OMAP_PREFETCH_IRQ        /* prefetch enabled irq mode */
};

For the present kernel TI's source code sets the transfer mode to NAND_OMAP_POLLED. Do any of the others work? (Particularly the DMA mode, and if so what channel should I specify?).

Thanks,
Ralph

  • Ah well, looks like that's a "no". I'll keep an eye on the Git to see if the situation gets improved.

    Ralph

  • Just wondering if there was any news on NAND read speed?

    Thanks,
    Ralph

  • Ralph,

    The prefetch mode (NAND_OMAP_PREFETCH_POLLED) works and marginally increases the NAND performance. The following patch should be incorporated in the kernel:

     

    Author: Saxena, Parth <parth.saxena@ti.com>
    Date:   Wed Sep 14 16:27:39 2011 +0530

        ti81xx: nand: changing nand transfer type to incorporate prefetch

        This patch changes the nand transfer type from polled to
        prefetch polled mode

        Signed-off-by: Saxena, Parth <parth.saxena@ti.com>

    diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
    index dc1c0d0..31021d9 100644
    --- a/arch/arm/mach-omap2/board-flash.c
    +++ b/arch/arm/mach-omap2/board-flash.c
    @@ -181,7 +181,7 @@ __init board_nand_init(struct mtd_partition *nand_parts,

            if (cpu_is_ti81xx()) {
                    board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_HW;
    -               board_nand_data.xfer_type = NAND_OMAP_POLLED;
    +               board_nand_data.xfer_type = NAND_OMAP_PREFETCH_POLLED;

                    /*
                     * For TI814x, the clock rate is different (110MHz).

     

    Regards,

    Parth

  • Hi, isn't NAND polled prefetch the mode that's been used all along anyway?

    Ralph

  • Ralph,

    As you can see from the patch, NAND_OMAP_POLLED mode was used before. The patch adds prefetch support.

    Regards,

    Parth

  • Oops, yes I see it was.

    Update: NAND_OMAP_PREFETCH_POLLED now gives me 5MB/s. No big improvement but I suppose it's a start.

    Thanks,

    Ralph

  • The running system is am3517 500Mhz. and boot from SD card.

    The Linux kernel is 2.6.37. 

    I do some nand flash test by below command.

    insmod /lib/modules/2.6.37-g01739e0-dirty/kernel/drivers/mtd/tests/mtd_speedtest.ko dev=5

    Modified the file  /drivers/mtd/nand/omap2.c for different combination test.

            pdata->ecc_opt          = OMAP_ECC_HAMMING_CODE_HW;
    // pdata->ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
    pdata->xfer_type = NAND_OMAP_PREFETCH_DMA;
    // pdata->xfer_type = NAND_OMAP_POLLED;

    It's weird  result  that the throughput is (SW ECC & DMA) > (HW ECC & PIO) > (HW ECC & DMA) .

    Does anyone know why?

    The detail test result is as below.

    ==================================================
    HW ECC & DMA

    [ 119.938293] mtd_speedtest: MTD device: 5
    [ 119.942382] mtd_speedtest: MTD device size 382205952, eraseblock size 131072, page size 2048, count of eraseblocks 2916, pages per eraseblock 64, OOB size 64
    [ 119.961608] mtd_speedtest: scanning for bad eraseblocks
    [ 120.174682] mtd_speedtest: scanned 2916 eraseblocks, 0 are bad
    [ 124.238769] mtd_speedtest: testing eraseblock write speed
    [ 266.683654] mtd_speedtest: eraseblock write speed is 2598 KiB/s
    [ 266.689819] mtd_speedtest: testing eraseblock read speed
    [ 385.300231] mtd_speedtest: eraseblock read speed is 3121 KiB/s
    [ 389.364654] mtd_speedtest: testing page write speed
    [ 535.661804] mtd_speedtest: page write speed is 2530 KiB/s
    [ 535.667510] mtd_speedtest: testing page read speed
    [ 657.929687] mtd_speedtest: page read speed is 3028 KiB/s
    [ 661.993621] mtd_speedtest: testing 2 page write speed
    [ 806.135772] mtd_speedtest: 2 page write speed is 2568 KiB/s
    [ 806.141571] mtd_speedtest: testing 2 page read speed
    [ 926.559906] mtd_speedtest: 2 page read speed is 3074 KiB/s
    [ 926.565673] mtd_speedtest: Testing erase speed
    [ 930.628692] mtd_speedtest: erase speed is 91236 KiB/s
    [ 930.633941] mtd_speedtest: finished

    ==================================================
    HW ECC & PIO

    [ 45.429870] mtd_speedtest: scanning for bad eraseblocks
    [ 45.643524] mtd_speedtest: scanned 2916 eraseblocks, 0 are bad
    [ 49.707214] mtd_speedtest: testing eraseblock write speed
    [ 189.160034] mtd_speedtest: eraseblock write speed is 2654 KiB/s
    [ 189.166229] mtd_speedtest: testing eraseblock read speed
    [ 277.977264] mtd_speedtest: eraseblock read speed is 4168 KiB/s
    [ 282.040924] mtd_speedtest: testing page write speed
    [ 424.620880] mtd_speedtest: page write speed is 2596 KiB/s
    [ 424.626525] mtd_speedtest: testing page read speed
    [ 516.346130] mtd_speedtest: page read speed is 4036 KiB/s
    [ 520.408782] mtd_speedtest: testing 2 page write speed
    [ 661.321777] mtd_speedtest: 2 page write speed is 2627 KiB/s
    [ 661.327667] mtd_speedtest: testing 2 page read speed
    [ 751.591369] mtd_speedtest: 2 page read speed is 4101 KiB/s
    [ 751.597076] mtd_speedtest: Testing erase speed
    [ 755.660064] mtd_speedtest: erase speed is 91236 KiB/s
    [ 755.665313] mtd_speedtest: finished

    ==================================================

    SW ECC & DMA
    [ 119.329681] mtd_speedtest: MTD device: 5
    [ 119.333770] mtd_speedtest: MTD device size 382205952, eraseblock size 131072, page size 2048, count of eraseblocks 2916, pages per eraseblock 64, OOB size 64
    [ 119.352996] mtd_speedtest: scanning for bad eraseblocks
    [ 119.566314] mtd_speedtest: scanned 2916 eraseblocks, 0 are bad
    [ 123.631713] mtd_speedtest: testing eraseblock write speed
    [ 207.163970] mtd_speedtest: eraseblock write speed is 4432 KiB/s
    [ 207.170196] mtd_speedtest: testing eraseblock read speed
    [ 265.946350] mtd_speedtest: eraseblock read speed is 6298 KiB/s
    [ 270.013580] mtd_speedtest: testing page write speed
    [ 357.244201] mtd_speedtest: page write speed is 4244 KiB/s
    [ 357.249816] mtd_speedtest: testing page read speed
    [ 419.498687] mtd_speedtest: page read speed is 5947 KiB/s
    [ 423.562957] mtd_speedtest: testing 2 page write speed
    [ 508.785797] mtd_speedtest: 2 page write speed is 4344 KiB/s
    [ 508.791595] mtd_speedtest: testing 2 page read speed
    [ 569.252227] mtd_speedtest: 2 page read speed is 6123 KiB/s
    [ 569.258026] mtd_speedtest: Testing erase speed
    [ 573.321228] mtd_speedtest: erase speed is 91191 KiB/s
    [ 573.326477] mtd_speedtest: finished
    [ 573.330139] =================================================
  • Juan,

    Have you also changed the "arch/arm/mach-omap2/board-flash.c" while updating the xfer type and ecc scheme. This file mentions these parameters in the "board_nand_init" function.

    Regards,

    Parth

  • Dear Parth,
    
    
    Thanks much for your reply.
    I don't change the board_nand_init().
    Should I assign it again if equal am3517?
    
    
    
    
    void
    __init board_nand_init(struct mtd_partition *nand_parts,
    u8 nr_parts, u8 cs, int nand_type)
    {
    board_nand_data.cs = cs;
    board_nand_data.parts = nand_parts;
    board_nand_data.nr_parts = nr_parts;
    board_nand_data.devsize = nand_type;

    board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs;

    if(cpu_is_omap3630())
    board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_HW;

    if (cpu_is_omap3517() || cpu_is_omap3505())
    board_nand_data.gpmc_t = NULL;

    if (cpu_is_ti81xx()) {
    board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_HW;
    board_nand_data.xfer_type = NAND_OMAP_POLLED;

    if (cpu_is_ti814x())
    board_nand_data.gpmc_t = NULL;
    }

    gpmc_nand_init(&board_nand_data);
    }
  • Juan,

    Yes, i recommend you to add "board_nand_data.ecc_opt" and "board_nand_data.xfer_type" options inside "if (cpu_is_omap3517() || cpu_is_omap3505())".

    Regards,

    Parth

  • Dear Parth,
    
    
    Thanks for your suggestion.
    But the result is the same. 
    Is there any possible?
    
    
            if (cpu_is_omap3517() || cpu_is_omap3505())
    {
    board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_HW;
    // board_nand_data.xfer_type = NAND_OMAP_POLLED;
    board_nand_data.xfer_type = NAND_OMAP_PREFETCH_DMA;
    board_nand_data.gpmc_t = NULL;
    printk("===================am3517\n");
    }
    
    
    regards,
    Ted
  • Dear Parth,

    Do you have the test results for comparison?

    Thanks very much.

    regards,

    Ted

  • Juan,

    I do not support DMA xfer type and hence I have not done the comparison so far. We have tested "NAND_OMAP_PREFETCH_POLLED" which marginally increases performance as compared to "NAND_OMAP_POLLED".

    Regards,

    Parth

  • Dear Parth,

    Thanks much for your information.

    Do you use hw ecc or sw ecc?

    How is the nand flash throughput that you test?

    Thanks,

    regards,

    Ted

  • hi i tried as per your command dd if=/dev/mtd7ro of=/dev/null bs=1M count=100

    but i am not able to see the speed n bytes copied.

    is there ny other command available or how can i measure the read write performance for NAND in linux when linux as well as filesystem is flashed in NAND

  • hi,
    If you would like to test nand flash speed, you can use kernel module.
    insmod mtd_speedtest.ko dev=7