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.

AM4377: AM4377 uboot reading flash through spi is slow

Part Number: AM4377


AM4377 accesses flash IS25LP256D through spi0, the command line executes sf read 80000000 100000 700000
Read the 7MB package to the memory address 0x80000000 takes 120s, measure the clock and data line of the spi, the clock is 48M,
But only 1B is transmitted at a time, and there is a 15us interval between each B.
How should the read speed be increased, or how can the spi clock be continuously output?

In addition, the measurement memory clock frequency is 100M. the DDR MT41K256M16 is 1866M. How should the input clock of ddr be set?
Is it set to 0x5AC[18:8]? But now set to 50|2 or 400|23, the actual measurement ddr input side is still 100M clock,
The register has been set successfully, and M2 is 2 divided. Setting value is
const struct dpll_params dpll_ddr = {400, 23, 1, -1, 1, -1, -1}; or{50, 2, 1, -1, 2, -1, -1};

[code path]:ti_uboot_201605sdk3205\drivers\spi
static int omap3_spi_read(struct omap3_spi_priv *priv, unsigned int len,
void *rxp, unsigned long flags)
{
int i, chconf;
ulong start;
int cnt; //crsc debug

/*SF:RD 0x80000000,L7340032(w8),0x4803012c,4803013c; */
printf("SF:RD 0x%x,L%d(w%d),0x%x,%x;\n", rxp, len, priv->wordlen,
&priv->regs->channel[priv->cs].chconf, &priv->regs->channel[priv->cs].rx); //crsc debug

chconf = readl(&priv->regs->channel[priv->cs].chconf);

/* Enable the channel */
omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN);

chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK);
chconf |= (priv->wordlen - 1) << 7;
chconf |= OMAP3_MCSPI_CHCONF_TRM_RX_ONLY;
chconf |= OMAP3_MCSPI_CHCONF_FORCE;
omap3_spi_write_chconf(priv, chconf);

writel(0, &priv->regs->channel[priv->cs].tx);

for (i = 0; i < len; i++) {
start = get_timer(0);
cnt = 0;
/* Wait till RX register contains data (RXS == 1) */
while (!(readl(&priv->regs->channel[priv->cs].chstat) &
OMAP3_MCSPI_CHSTAT_RXS)) {
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;
}
cnt++;
}

if ((i%0x80000) == 0)
printf("%d;", cnt); //crsc debug

/* Disable the channel to prevent furher receiving */
if (i == (len - 1))
omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS);

/* Read the data */
unsigned int *rx = &priv->regs->channel[priv->cs].rx;
if (priv->wordlen > 16)
((u32 *)rxp)[i] = readl(rx);
else if (priv->wordlen > 8)
((u16 *)rxp)[i] = (u16)readl(rx);
else
((u8 *)rxp)[i] = (u8)readl(rx);
}

if (flags & SPI_XFER_END) {
chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
omap3_spi_write_chconf(priv, chconf);
}

return 0;
}

[uboot info]:
omap3 spi speed 48000000Hz;
SF:RD 0x9ef16f98,L5(w8),0x4803012c,4803013c;
0;SF: Lock ops not supported for 9d flash
SF:RD 0x9ef16f97,L1(w8),0x4803012c,4803013c;
0;SF: Detected IS25LP256D with page size 256 Bytes, erase size 64 KiB, total 32 MiB
: returns 0
device 0 offset 0x100000, size 0x700000
SF:RD 0x80000000,L7340032(w8),0x4803012c,4803013c;
0;0;0;0;0;0;0; ...

BOOT># md 0x48030100
48030100: 0000002b 00000000 00000000 00000000 +...............
48030110: 00000015 00000001 00000000 00000000 ................
48030120: 00000001 00000000 00000004 00060000 ................
48030130: 00000000 00000000 00000000 00000000 ................
48030140: 00060000 00000000 00000000 00000000 ................
48030150: 00000000 00060000 00000000 00000000 ................
48030160: 00000000 00000000 00060000 00000000 ................

ddr clk:
CRSC># md 0x44DF2D20
44df2d20: 00000007 00000001 00000000 0003e817 ................
44df2d30: 00000000 00000000 0000022a 00000228 ........*...(...
44df2d40: 00000024 00000000 00000000 00000000 $...............
44df2d50: 00000000 00000000 00000000 00000000 ................
44df2d60: 00000007 00000001 00000000 00025817 .............X..
44df2d70: 00000201 00000000 00000000 00000000 ................
44df2d80: 00000000 00000000 00000000 00000000 ................
44df2d90: 00000000 00000000 00000000 00000000 ................
44df2da0: 00000007 00000001 00000000 00019017 ................
44df2db0: 00000221 00000000 00000221 00000000 !.......!.......
44df2dc0: 00000000 00000000 00000000 00000000 ................
44df2dd0: 00000000 00000000 00000000 00000000 ................
44df2de0: 00000007 00000001 00000000 0403c017 ................
44df2df0: 00000285 00000000 00000000 00000000 ................
44df2e00: 00000000 00000000 00000000 00000000 ................
44df2e10: 00000000 00000300 00000000 00000000 ................

thank you!

  • Please post which Linux version you are using.
  • [spl and uboot version]
    ti_uboot_201605sdk3205(u-boot-2016.05+gitAUTOINC+6c5519b6fc_3.2.0.5)
    [sdk]
    ti-processor-sdk-linux-am437x-evm-03.02.00.05-Linux-x86-Install.bin

    VirtualBox:~/ti-processor-sdk-linux-am437x-evm-03.02.00.05/board-support/u-boot-2016.05+gitAUTOINC+6c5519b6fc-g6c5519b6fc$ cat /proc/version
    Linux version 4.10.0-28-generic (buildd@lgw01-12) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4) ) #32~16.04.2-Ubuntu SMP Thu Jul 20 10:19:48 UTC 2017
    VirtualBox:~/ti-processor-sdk-linux-am437x-evm-03.02.00.05/board-support/u-boot-2016.05+gitAUTOINC+6c5519b6fc-g6c5519b6fc$ uname -a
    Linux x-VirtualBox 4.10.0-28-generic #32~16.04.2-Ubuntu SMP Thu Jul 20 10:19:48 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
    VirtualBox:~/ti-processor-sdk-linux-am437x-evm-03.02.00.05/board-support/u-boot-2016.05+gitAUTOINC+6c5519b6fc-g6c5519b6fc$ lsb_release -a
    No LSB modules are available.
    Distributor ID: Ubuntu
    Description: Ubuntu 16.04.3 LTS
    Release: 16.04
    Codename: xenial

    thank you!

  • Execute the command line sf read is in the uboot stage, the kernel is not loaded,Using the spl and uboot compiled by TI's SDK, and the SPI uses the OMAP3 branch.

  • All read is removed(for (i = 0; i < len; i++)), time-consuming has not changed (512k + printf =10s), and finally found 'start = get_timer (0); ' this line runs too long. After removing it, the time is 512k+printf <1s, and the code path is get_ticks lib/time.c. What causes the time to be long? Thank you!
  • Remove get_timer and use count++ mode to calculate the timeout time, when SPI clock 48M, reading 7MB boot package from flash to memory take time 10s ~ 12s, whether it can improve? Thank you!
  • Hello,

    With regards to the input speed, I am wondering if you have set the appropriate system clock on the BOOT[15:14] pins. If possible, please share the register value of "CTRL_STS Register (Offset = 40h)". Based on the boot pins, uboot will pick the appropriate PLL dividers.

    Regards,
    Krunal
  • Thank you for your reply!
    SYSBOOT pin [15]is set low,[14]is set high(24M),and register 0x44E10040[23:22]=1(24M) is OK
    BOOT># md 44e10000
    44e10000: 4f000100 00000000 00000000 00000000 ...O............
    44e10010: 0000002a 00000000 00000000 00000000 *...............
    44e10020: 00000000 00000000 00000000 00000000 ................
    44e10030: 00000000 00000000 00000000 00000000 ................
    44e10040: 02400309 00000000 00000000 00000000 ..@.............

    Now by changing the flash to read RX fifo to count waiting, the rate of reading 5MB flash through SPI is 10s, which is close to the startup time requirement.
    Excuse me, what is the reasonable reading rate?
    In addition, how should I set the clock and divider of my DDR clock?Is there an example?

    Thank you!
  • Hello,

    Please refer to the following TI document.

    Regards,

    Krunal