[U-Boot] "No status update" errors in OMAP mmc_send_cmd()

Greetings,
I've been fighting an odd problem with a custom OMAP4 board throwing MMC errors. It seems that a 4-bit-wide uSD card on MMC1 works but an 8-bit-wide eMMC part on MMC2 has problems.
As sometimes happens, in trying to track down the problem the presence of a debugging printf() masked the error.
Just now I've finally gotten a good trace on this. In drivers/mmc/omap_hsmmc.c near line 380, if I have:
writel(cmd->cmdarg, &mmc_base->arg); writel((cmd->cmdidx << 24) | flags, &mmc_base->cmd); printf("%s : @ %p cmd 0x%08x arg 0x%08x\n", __func__, mmc_base, cmd->cmdidx, cmd->cmdarg);
With or without that printf() the code fails when I select MMC2 (eMMC):
u-boot # mmc dev 1 mmc_send_cmd : @ 480b4100 cmd 0x00000000 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000008 arg 0x000001aa mmc_send_cmd : @ 480b4100 cmd 0x00000037 arg 0x00000000 mmc_send_cmd : timeout on cmd 55. No status update (base 480b4100) << 1s delay mmc_send_cmd : @ 480b4100 cmd 0x00000000 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000002 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000003 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000009 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x0000000d arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000007 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000008 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000008 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000006 arg 0x03b90100 mmc_send_cmd : @ 480b4100 cmd 0x0000000d arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000008 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000006 arg 0x03b70100 mmc_send_cmd : @ 480b4100 cmd 0x0000000d arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000008 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000010 arg 0x00000200 mmc_send_cmd : @ 480b4100 cmd 0x00000011 arg 0x00000000 mmc1(part 0) is current device
If I instead put the printf() or a udelay(20) (anything less than 20 still failed) *between* the two writel() calls it works:
u-boot # mmc dev 1 mmc_send_cmd : @ 480b4100 cmd 0x00000000 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000008 arg 0x000001aa mmc_send_cmd : @ 480b4100 cmd 0x00000037 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000000 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000001 arg 0x40300080 mmc_send_cmd : @ 480b4100 cmd 0x00000002 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000003 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000009 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x0000000d arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000007 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000008 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000008 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000006 arg 0x03b90100 mmc_send_cmd : @ 480b4100 cmd 0x0000000d arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000008 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000006 arg 0x03b70100 mmc_send_cmd : @ 480b4100 cmd 0x0000000d arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000008 arg 0x00000000 mmc_send_cmd : @ 480b4100 cmd 0x00000010 arg 0x00000200 mmc_send_cmd : @ 480b4100 cmd 0x00000011 arg 0x00000000 mmc1(part 0) is current device
So writing to the command register "too soon" after writing to the dependent data registers sometimes fails.
Obviously a magic-number udelay() is a hack. I'm going to dive into the data sheet but wanted to ask here if this is familiar to anyone.
Thanks, -Michael Cashwell

Michael Cashwell <mboards <at> prograde.net> writes:
Greetings,
I've been fighting an odd problem with a custom OMAP4 board throwing MMC
errors.
It seems that a 4-bit-wide uSD card on MMC1 works but an 8-bit-wide eMMC part on MMC2 has problems.
As sometimes happens, in trying to track down the problem the presence of a debugging printf() masked the error.
Just now I've finally gotten a good trace on this. In drivers/mmc/omap_hsmmc.c near line 380, if I have:
writel(cmd->cmdarg, &mmc_base->arg); writel((cmd->cmdidx << 24) | flags, &mmc_base->cmd); printf("%s : <at> %p cmd 0x%08x arg 0x%08x\n", __func__, mmc_base,
cmd->cmdidx, cmd->cmdarg);
With or without that printf() the code fails when I select MMC2 (eMMC):
<snip>
If I instead put the printf() or a udelay(20) (anything less than 20 still failed) *between* the two writel() calls it works:
I had a similar problem with recent u-boot on OMAP 4430SDP board. With my rather old MMC, I was unable to boot at all:
U-Boot SPL 2013.04 (May 10 2013 - 08:20:30) OMAP4430 ES2.1 OMAP SD/MMC: 0 mmc_send_cmd : timeout: No status update Card did not respond to voltage select! spl: mmc init failed: err - -17 ### ERROR ### Please RESET the board ###
With newer MMC, I can boot, but I see an error from u-boot:
mmc_send_cmd : timeout: No status update
Adding udelay to the place you mention fixes both problems.
Tomi
participants (2)
-
Michael Cashwell
-
Tomi Valkeinen