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.

AM3352: AM3352 u-boot SPI read too slow

Part Number: AM3352


Hi Expert,

uboot version is u-boot-2018.01
 

 u-boot SPI read too slow

SPI speed is 48MHz,#define CONFIG_SF_DEFAULT_SPEED 48000000

=> time sf read ${rdaddr}   0x0 0xA00000
device 0 offset 0x0, size 0xa00000
SF: 10485760 bytes @ 0x0 Read: OK

time: 33.014 seconds
→ 310.17 KB/s

My customer had checked the data.

https://e2e.ti.com/support/processors/f/791/t/468270
https://e2e.ti.com/support/processors/f/791/t/392536

But he cannot improve the SPI read performance

Could you give some suggestions?

Thanks

Daniel

  • Hi Daniel,
    I ran a quick test @u-boot prompt with SDK 6.3 on AM335x GP EVM.
    I enabled "turbo" mode in MCSPI_CH0CONF register in omap3_spi_read(), see attachment for code change.
    The SPI read speed is listed below => ~1.12 MBytes/second

    => sf probe 0
    SF: Detected w25q64cv with page size 256 Bytes, erase size 4 KiB, total 8 MiB
    => time sf read ${rdaddr} 0x0 0x800000
    device 0 whole chip
    SF: 8388608 bytes @ 0x0 Read: OK
    time: 7.471 seconds

    Best,

    -Hong

    diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c
    index c7fcf050a5..8bcf6a6c9d 100644
    --- a/drivers/spi/omap3_spi.c
    +++ b/drivers/spi/omap3_spi.c
    @@ -203,6 +203,7 @@ static int omap3_spi_read(struct omap3_spi_priv *priv, unsigned int len,
     	chconf |= (priv->wordlen - 1) << 7;
     	chconf |= OMAP3_MCSPI_CHCONF_TRM_RX_ONLY;
     	chconf |= OMAP3_MCSPI_CHCONF_FORCE;
    +	chconf |= OMAP3_MCSPI_CHCONF_TURBO;
     	omap3_spi_write_chconf(priv, chconf);
     
     	writel(0, &priv->regs->channel[priv->cs].tx);
    

  • Hi, I'm the customer

    I've tried enable turbo mode, but there is no difference.

    => md 0x4803012C 1
    4803012c: 00060000

    => sf probe 0
    SF: Detected mx25l25635f with page size 256 Bytes, erase size 64 KiB, total 32 MiB
    => time sf read ${rdaddr} 0x0 0xA00000
    device 0 offset 0x0, size 0xa00000
    SF: 10485760 bytes @ 0x0 Read: OK

    time: 21.088 seconds

    The improvement from ~300KB/s to ~500KB/s is due to the deletion of get_timer() calls. (refer to https://e2e.ti.com/support/processors/f/791/t/794109?AM4377-AM4377-uboot-reading-flash-through-spi-is-slow)

    I use "counter++ > SPI_WAIT_TIMEOUT" instead of "get_timer(start) > SPI_WAIT_TIMEOUT" to do timeout handling, which improves a lot.

    I'm not sure whether this modification will cause side effects. Currently, it works stably.

    However, ~500KB/s is not enough. I wish I can reach your speed. (~1.12 MBytes/second is OK!)

    I've tried dcache on command, also has no effect.

    How can I check my environment is the same as yours?

    Thanks!

    Best,

    Howard

  • Hi Howard,
    For your reference to check MCSPI_CH0CONF register value, I ran another test as listed below.

    => md 0x4803012C 1
    4803012c: 00060000                               ....
    => sf probe 0
    SF: Detected w25q64cv with page size 256 Bytes, erase size 4 KiB, total 8 MiB
    => md 0x4803012C 1
    4803012c: 000913c7                               ....
    => time sf read ${rdaddr} 0x0 0x800000
    device 0 whole chip
    SF: 8388608 bytes @ 0x0 Read: OK
    time: 3.947 seconds
    => md 0x4803012C 1
    4803012c: 000913c7    

    Please note that:
    1. SPI clock is 24MHz as "#define CONFIG_SF_DEFAULT_SPEED 24000000" in "/include/configs/am335x_evm.h"
    4803012c: 000913c7 => TURBO mode, CLKG=0 & CLKD=1 => FOUT=48/2=24MHz
    2. For testing purpose only, I removed below code snippet from omap3_spi_read() in "drivers/spi/omap3_spi.c" for testing purpose.
    ==> 2.12 MBytes/s

    			if (get_timer(start) > SPI_WAIT_TIMEOUT) {
    				printf("SPI RXS timed out, status=0x%08x\n",
    					readl(&priv->regs->channel[priv->cs].chstat));
    				return -1;
    			}

    Best,

    -Hong

  • Hi Hong,

    Thank you for your reply.

    I found that there is something strange.

    After sf probe command, the register value (from md command) is still 0x00060000, though I've patched the turbo mode to omap3_spi_read(), and change the SPI speed to 24 MHz.

    (We use 48MHz as default speed before.)

    #define CONFIG_SF_DEFAULT_SPEED		24000000 // originally 48000000

    CNAND:  256 MiB
    MMC:
    OMAP3_MCSPI_CHCONF=0x001913c7 (0x4803012c)
    OMAP3_MCSPI_CHCONF=0x001913c7 (0x4803012c)
    OMAP3_MCSPI_CHCONF=0x001913c7 (0x4803012c)
    SF: Detected mx25l25635f with page size 256 Bytes, erase size 64 KiB, total 32 MiB
    OMAP3_MCSPI_CHCONF=0x001913c7 (0x4803012c)
    Net:   cpsw, usb_ether
    Hit any key to stop autoboot:  0
    => md 0x4803012C 1
    4803012c: 00060000                               ....
    => sf probe 0
    OMAP3_MCSPI_CHCONF=0x001913c7 (0x4803012c)
    OMAP3_MCSPI_CHCONF=0x001913c7 (0x4803012c)
    OMAP3_MCSPI_CHCONF=0x001913c7 (0x4803012c)
    SF: Detected mx25l25635f with page size 256 Bytes, erase size 64 KiB, total 32 MiB
    => md 0x4803012C 1
    4803012c: 00060000                               ....
    =>

    However, the printf message in omap3_spi_read() shows that the register value is 0x001913c7.

    After further tracing code.

    I am not sure whether it is because the spi_release_bus(spi) call in spi_flash_read_common() will reset the register,

    and the _omap3_spi_set_mode() call raises OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1 → 0x60000.

    I can't explain why your md commands show 000913c7, but I think the turbo mode has been enabled during reading.

    The question is, why the speed is still slow?

    Best,

    Howard

  • Hi Hong,

    I finally got the answer!

    It was because the watchdog reset call we've added in the reading loop...

    Reducing the watchdog reset frequency solve the issue.

    But I still have to remove all get_timer() calls to reach your speed. It is okay to use counter or simply remove the SPI_WAIT_TIMEOUT statement to let watchdog reset the system.

    Thank you for your kind help!

    Howard

  • Hi Howard,
    It is good to know you had SPI read speed test working.
    <get_timer(start) > SPI_WAIT_TIMEOUT> is to break out of SPI read loop when waiting time for SPI data ready is over max timeout due to abnormal situation.
    Your idea of using simple counter++ to replace get_timer() would work.

    Best,

    -Hong