[#3991] mmc_spi not working out of the box.
Submitted By: Hans Eklund
Open Date
2008-03-27 11:40:30 Close Date
2008-12-01 23:16:02
Priority:
Medium High Assignee:
Yi Li
Status:
Closed Fixed In Release:
N/A
Found In Release:
N/A Release:
svn head
Category:
Drivers Board:
STAMP
Processor:
BF537 Silicon Revision:
Is this bug repeatable?:
Yes Resolution:
Fixed
Uboot version or rev.:
Toolchain version or rev.:
App binary format:
N/A
Summary: mmc_spi not working out of the box.
Details:
Introduction:
After a discussion the last couple of weeks with the spi-devel community, mmc_spi developers and maintainer David Brownell and others i believe it would be good to evaluate the mmc_spi driver from the mainline Linux source tree(drivers/mmc/host/mmc_spi.c), making it work vs. blackfin spi master driver.
After a small patch from Bryan last night i have built it vs uClinux-dist svn head and inserted it on a STAMP537 board using the Rubico MMC/SD addon board. I have yet to detect a card with it. I did not expect it to work either.:)
The driver does not support concurrent access just yet. But there is a patch for it but it would require the Blackfin SPI Master driver to be patched to fit a new exclusive access api for the spi framework. It has been tested on the au1550_spi master controller driver by Jan Nikitenko, one of the mmc_spi developers.
I thought it would be best to add a tracker for this topic since it seem to be reuqested from several users to have a working MMC/SD solution and to note any progress. In the end it would imply my old spi_mmc driver to be put on the shelf even though i made a fix for the concurrent access. This is the best solution in the long run.
Now, about the actual error:
I do this test:
$ modprobe mmc_block
$ modprobe mmc_probe
$ modprobe mmc_spi
I hook the scope up and see no data on MISO and MOSI, clock and CS is alive though. I guess the data dont reach the master driver. Could be the dma_map_page not working as intended, or any other dma/cache related problem. Should do a non-dma mode test and also view massive spi debug prints for now.
/Hans
Follow-ups
--- Hans Eklund 2008-03-27 12:25:33
Why not post progress, someone might just be interested:
Turned off dma mode, and voilá. I can read data blocks. Writing blocks seem to
fail since kernel reports an end_request error on fdisk and any other kinds of
induced writes. I allmost though block writes failed, but this nasty tell
another story:
root:/> echo "hello" > /dev/mmcblk0
mmcblk0: error -71 transferring data
end_request: I/O error, dev mmcblk0, sector 1
Buffer I/O error on device mmcblk0, logical block 0
lost page write due to I/O error on mmcblk0
root:/> dd if=/dev/mmcblk0 bs=6 count=1
hello
1+0 records in
1+0 records out
root:/>
So data block reaches card but an error is reported upwards. Multiple echo to
the card allways report error, multiple dd (reads) report end_request error one
out of ten times roughly. Test done also with module removed/reloaded and other
cards in between, written data was actually written.
Pulling my beard for awhile a believe it is probably a status check command
that report a false error for some reason.
Next: remove status check from driver after block writes.
My configuration, uclinux-dist svn head, add this to stamp.c:
#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
static struct bfin5xx_spi_chip mmc_spi_chip_info = {
.enable_dma = 0,
.bits_per_word = 8,
};
#endif
And addition to static struct spi_board_info bfin_spi_board_info[] __initdata
#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
{
.modalias = "mmc_spi",
.max_speed_hz = 5000000, /* max spi clock (SCK) speed in HZ
*/
.bus_num = 0,
.chip_select = 1,
.platform_data = NULL,
.controller_data = &mmc_spi_chip_info,
.mode = SPI_MODE_3,
},
#endif
Slow clock due to old crappy scope.
--- Hans Eklund 2008-03-27 13:18:11
Ok full debug mode(dmesg -n 8) tells me some/many blocks have CRC errors during
block reads. Dmesg -n 4(no debug messages from driver, but end_request will
still print): no errors, all fine. Writing still reports all kinds of error.
Somewhat strange. Will turn off CRC checking and verify data blocks manually.
--- Hans Eklund 2008-03-27 14:42:20
Allright, some success after some tweaking.
1) Turn off SPI crc checking by doing this when insterting mmc_block
$ modprobe mmc_block use_spi_crc=0
2) Need to modify mmc_spi.c to ignore status checks from block writes since it
seem to always be ff even though block was written ok. I have my ideas why it
happens, but this fix will do for now.
Can fdisk(create and write new partition), mkdosfs, mount it and write to some
extent. All using a simple Verbatim 256Mb SD card. Some end_request failiures
though on one try. md5sum verified files after remount.
All for tonight.
--- Hans Eklund 2008-03-28 11:20:07
Found out it is probably better to keep the crc checking and implement a block
read/write retry routine instead. Even more stable now. But not safe. Some
spooky errors now and then. MMC/SD card seem to sometimes be trapped in a mode
where i need to remove card, remove module, insert card and reload module. I
recognize this behaviour from "my" spi_mmc driver. Will se if i would
need to implement a low level reset if all else fails.
I include patch files for stamp.c and mmc_spi.c files at its current state if
anyone would like to continue/evaluate the work.
--- Bryan Wu 2008-04-02 02:36:05
Hi Hans,
I am here trying to hook up your patch with MMC_SPI driver.
1. I cannot found module named mmc_probe
---
root:/> modprobe mmc_probe
modprobe: module mmc_probe not found
modprobe: failed to load module mmc_probe
---
Could you please upload your .config file for me?
2. /dev/mmcblock0 does not exist.
---
root:/> modprobe mmc_block
root:/> modprobe mmc_probe
modprobe: module mmc_probe not found
modprobe: failed to load module mmc_probe
root:/> modprobe mmc_spi
mmc_spi spi0.1: ASSUMING SPI bus stays unshared!
mmc_spi spi0.1: ASSUMING 3.2-3.4 V slot power
mmc_spi spi0.1: SD/MMC host mmc0, no DMA, no WP, no poweroff
mmc_spi spi0.1: requested mode not fully supported
mmc_spi spi0.1: can't change chip-select polarity
root:/> ls /dev
console mem ram1 ram14 ram5 random ttyBF0
full null ram10 ram15 ram6 rtc0 urandom
kmem ptmx ram11 ram2 ram7 sport0 watchdog
kmsg pts ram12 ram3 ram8 sport1 zero
log ram0 ram13 ram4 ram9 tty
---
Sorry for the replying delay, because I am struggling in the USB OTG bugs.
Thanks
-Bryan
--- Hans Eklund 2008-04-02 03:56:03
Sorry, in the haste i was sloppy, it should be
$ modprobe mmc_core
and not mmc_probe. My fault. Hope to continue testing soon. Is occupied with
other work for a few days now.
/Hans
--- Bryan Wu 2008-04-02 06:34:54
I still cannot found /dev/mmcblock0
--
root:/> modprobe mmc_core
root:/> modprobe mmc_block
root:/> modprobe mmc_spi
mmc_spi spi0.1: ASSUMING SPI bus stays unshared!
mmc_spi spi0.1: ASSUMING 3.2-3.4 V slot power
mmc_spi spi0.1: SD/MMC host mmc0, no DMA, no WP, no poweroff
mmc_spi spi0.1: requested mode not fully supported
mmc_spi spi0.1: can't change chip-select polarity
root:/> ls /dev/
console mem ram1 ram14 ram5 random ttyBF0
full null ram10 ram15 ram6 rtc0 urandom
kmem ptmx ram11 ram2 ram7 sport0 watchdog
kmsg pts ram12 ram3 ram8 sport1 zero
log ram0 ram13 ram4 ram9 tty
root:/>
--
Need I create it manually?
-Bryan
--- Hans Eklund 2008-04-03 02:52:43
Nope, no need to create the device nodes, they should pop up once the driver
finds a card. It does not need to be partitioned correctly, the "whole
disk"-partition mmcblk0 should allways appear. I´ll post a step by step
instruction and verify the patches my self soon.
--- Hans Eklund 2008-04-08 12:57:09
Ok. short guide here. Can format a card and do basic data transfers.
I did this test with 5Mhz SPI clock:
This is a dump from a testrun, Verbatim 256mb SD card:
root:/> modprobe mmc_core use_spi_crc=0
root:/> modprobe mmc_block
root:/> modprobe mmc_spi use_tdr=0
mmc_spi spi0.1: ASSUMING SPI bus stays unshared!
mmc_spi spi0.1: ASSUMING 3.2-3.4 V slot power
mmc_spi spi0.1: requested mode not fully supported
mmc_spi spi0.1: can't change chip-select polarity
mmc_spi spi0.1: SD/MMC host mmc0, no DMA, no WP, no poweroff
root:/> mmc0: new SD card on SPI
mmcblk0: mmc0:0000 SD256 249088KiB
mmcblk0:<7>mmc0: starting CMD18 arg 00000000 flags 000000b5
p1 p2
root:/> mkdosfs /dev/mmcblk0p1
mkdosfs 2.10 (22 Sep 2003)
root:/>
Should work better, you could try witout the use_spi_crc force parameter also.
Need to test some more cards.
/Hans
--- Bryan Wu 2008-05-08 00:02:25
Hi Hans,
Sorry for long silence. I tested the MMC card on my side. But this driver does
not work.
1. I did this test with 5Mhz SPI clock:
.max_speed_hz = 5000000,
System hangs and was reset by watchdogd
--
root:/>
root:/> modprobe mmc_core use_spi_crc=0
root:/> modprobe mmc_block
root:/> modprobe mmc_spi use_tdr=0
mmc_spi spi0.4: ASSUMING SPI bus stays unshared!
mmc_spi spi0.4: ASSUMING 3.2-3.4 V slot power
mmc_spi spi0.4: SD/MMC host mmc0, no DMA, no WP, no poweroff
--
2. set SPI clock for 2M, I can detect the card, but mkdosfs failed.
--
root:/> modprobe mmc_core use_spi_crc=0
root:/> modprobe mmc_block
root:/> modprobe mmc_spi use_tdr=0
mmc_spi spi0.4: ASSUMING SPI bus stays unshared!
mmc_spi spi0.4: ASSUMING 3.2-3.4 V slot power
mmc_spi spi0.4: SD/MMC host mmc0, no DMA, no WP, no poweroff
mmc_spi spi0.4: requested mode not fully supported
mmc_spi spi0.4: can't change chip-select polarity
root:/> mmc0: new MMC card on SPI
mmcblk0: mmc0:0001 MMC512 495104KiB
mmcblk0:<7>mmc0: starting CMD18 arg 00000000 flags 000000b5
p1 p2
root:/>
root:/>
root:/> mkdosfs /dev/mmcblk0p1
mkdosfs 2.11 (12 Mar 2005)
mmcblk0: error -53 sending read/write command
end_request: I/O error, dev mmcblk0, sector 78
Buffer I/O error on device mmcblk0p1, logical block 8
lost page write due to I/O error on mmcblk0p1
end_request: I/O error, dev mmcblk0, sector 80
end_request: I/O error, dev mmcblk0, sector 82
end_request: I/O error, dev mmcblk0, sector 84
mmcblk0: error -53 sending read/write command
end_request: I/O error, dev mmcblk0, sector 118
end_request: I/O error, dev mmcblk0, sector 120
end_request: I/O error, dev mmcblk0, sector 122
end_request: I/O error, dev mmcblk0, sector 124
mmcblk0: error -53 sending read/write command
end_request: I/O error, dev mmcblk0, sector 142
end_request: I/O error, dev mmcblk0, sector 144
end_request: I/O error, dev mmcblk0, sector 146
end_request: I/O error, dev mmcblk0, sector 148
mmcblk0: error -110 sending read/write command
end_request: I/O error, dev mmcblk0, sector 150
end_request: I/O error, dev mmcblk0, sector 152
end_request: I/O error, dev mmcblk0, sector 154
end_request: I/O error, dev mmcblk0, sector 156
mmcblk0: error -53 sending read/write command
end_request: I/O error, dev mmcblk0, sector 174
end_request: I/O error, dev mmcblk0, sector 176
end_request: I/O error, dev mmcblk0, sector 178
end_request: I/O error, dev mmcblk0, sector 180
mmcblk0: error -53 sending read/write command
end_request: I/O error, dev mmcblk0, sector 198
end_request: I/O error, dev mmcblk0, sector 200
end_request: I/O error, dev mmcblk0, sector 202
end_request: I/O error, dev mmcblk0, sector 204
mmcblk0: error -53 sending read/write command
end_request: I/O error, dev mmcblk0, sector 230
end_request: I/O error, dev mmcblk0, sector 232
end_request: I/O error, dev mmcblk0, sector 234
end_request: I/O error, dev mmcblk0, sector 236
mmcblk0: error -53 sending read/write command
end_request: I/O error, dev mmcblk0, sector 262
end_request: I/O error, dev mmcblk0, sector 264
end_request: I/O error, dev mmcblk0, sector 266
end_request: I/O error, dev mmcblk0, sector 268
mmcblk0: error -110 sending read/write command
end_request: I/O error, dev mmcblk0, sector 270
end_request: I/O error, dev mmcblk0, sector 272
end_request: I/O error, dev mmcblk0, sector 274
end_request: I/O error, dev mmcblk0, sector 276
mmcblk0: error -110 sending read/write command
end_request: I/O error, dev mmcblk0, sector 294
end_request: I/O error, dev mmcblk0, sector 296
end_request: I/O error, dev mmcblk0, sector 298
end_request: I/O error, dev mmcblk0, sector 300
mmcblk0: error -53 sending read/write command
end_request: I/O error, dev mmcblk0, sector 302
end_request: I/O error, dev mmcblk0, sector 304
end_request: I/O error, dev mmcblk0, sector 306
end_request: I/O error, dev mmcblk0, sector 308
mmcblk0: error -110 sending read/write command
end_request: I/O error, dev mmcblk0, sector 310
end_request: I/O error, dev mmcblk0, sector 312
end_request: I/O error, dev mmcblk0, sector 314
end_request: I/O error, dev mmcblk0, sector 316
mmcblk0: error -110 sending read/write command
end_request: I/O error, dev mmcblk0, sector 334
end_request: I/O error, dev mmcblk0, sector 336
end_request: I/O error, dev mmcblk0, sector 338
end_request: I/O error, dev mmcblk0, sector 340
mmcblk0: error -53 sending read/write command
end_request: I/O error, dev mmcblk0, sector 342
end_request: I/O error, dev mmcblk0, sector 344
end_request: I/O error, dev mmcblk0, sector 346
end_request: I/O error, dev mmcblk0, sector 348
mmcblk0: error -110 sending read/write command
end_request: I/O error, dev mmcblk0, sector 366
end_request: I/O error, dev mmcblk0, sector 368
end_request: I/O error, dev mmcblk0, sector 370
end_request: I/O error, dev mmcblk0, sector 372
mmcblk0: error -53 sending read/write command
end_request: I/O error, dev mmcblk0, sector 374
end_request: I/O error, dev mmcblk0, sector 376
end_request: I/O error, dev mmcblk0, sector 378
end_request: I/O error, dev mmcblk0, sector 380
mmcblk0: error -53 sending read/write command
end_request: I/O error, dev mmcblk0, sector 398
end_request: I/O error, dev mmcblk0, sector 400
end_request: I/O error, dev mmcblk0, sector 402
end_request: I/O error, dev mmcblk0, sector 404
mmcblk0: error -110 sending read/write command
end_request: I/O error, dev mmcblk0, sector 430
printk: 67 messages suppressed.
Buffer I/O error on device mmcblk0p1, logical block 184
lost page write due to I/O error on mmcblk0p1
end_request: I/O error, dev mmcblk0, sector 432
end_request: I/O error, dev mmcblk0, sector 434
end_request: I/O error, dev mmcblk0, sector 436
mmcblk0: error -53 sending read/write command
end_request: I/O error, dev mmcblk0, sector 438
end_request: I/O error, dev mmcblk0, sector 440
end_request: I/O error, dev mmcblk0, sector 442
end_request: I/O error, dev mmcblk0, sector 444
mmcblk0: error -53 sending read/write command
end_request: I/O error, dev mmcblk0, sector 462
end_request: I/O error, dev mmcblk0, sector 464
end_request: I/O error, dev mmcblk0, sector 466
end_request: I/O error, dev mmcblk0, sector 468
mmcblk0: error -110 sending read/write command
end_request: I/O error, dev mmcblk0, sector 486
end_request: I/O error, dev mmcblk0, sector 488
end_request: I/O error, dev mmcblk0, sector 490
end_request: I/O error, dev mmcblk0, sector 492
mmcblk0: error -53 sending read/write command
end_request: I/O error, dev mmcblk0, sector 494
end_request: I/O error, dev mmcblk0, sector 496
end_request: I/O error, dev mmcblk0, sector 498
end_request: I/O error, dev mmcblk0, sector 500
mmcblk0: error -110 sending read/write command
end_request: I/O error, dev mmcblk0, sector 550
end_request: I/O error, dev mmcblk0, sector 552
end_request: I/O error, dev mmcblk0, sector 554
end_request: I/O error, dev mmcblk0, sector 556
mmcblk0: error -53 sending read/write command
end_request: I/O error, dev mmcblk0, sector 582
end_request: I/O error, dev mmcblk0, sector 584
end_request: I/O error, dev mmcblk0, sector 586
end_request: I/O error, dev mmcblk0, sector 588
root:/>
--
It looks like the compatibility of this driver is not very good.
-Bryan
--- Sonic Zhang 2008-10-20 23:51:16
Yi took over the investigation of mainline spi mmc driver.
--- Sonic Zhang 2008-10-20 23:51:51
Yi took over the investigation of mainline spi mmc driver.
--- Yi Li 2008-12-01 02:24:31
Wolfgang Mües fixed problem in spi_bfin5xx.c and mmc_spi.c, finally the mmc_spi
driver works on Blackfin. Details of the solutions can be found at:
blackfin.uclinux.org/gf/project/uclinux-dist/forum/?action=ForumBrowse&forum_id=39&_forum_action=ForumMessageBrowse&thread_id=31066.
Also at:
www.mail-archive.com/uclinux-dist-devel@blackfin.uclinux.org/msg01038.html.
Here is summary:
For spi_bfin5xx.c:
1. Rewrite of the non-dma data transfer functions to use only ONE mode of TIMOD
(TIMOD = 0x1): With TIMOD=0, it was not possible to set the TX bit pattern. So
the TDBR = 0xFFFF inside the read calls won't work.
2. Clear SPI_RDBR before reading (and before duplex transfer). Otherwise the
garbage data will get read. Since mmc_spi uses a lot of duplex transfer, this is
the main cause of mmc_spi failure.
3. Poll RXS for transfer completion. Polling SPIF or TXS cannot guarantee
transfer finish. This may leave garbage data in buffer and affect next
transfer.
--- Yi Li 2008-12-01 22:11:09
For mmc_spi.c:
change log:
- Use jiffies for busy waiting. No need to deal with ns-Precision and 64 bit
variables if all we need is timeouts in the ms area.
- Release CPU time if busy timeout gets long.
- Extend write timeout to 1s to cope with cheap high capacity SDHC cards which
got totaly upset if we write large chunks of data at once.
- Allow for the fact that a card is not able to send the response token after a
data transfer in time. The token may be delayed a few bits(!).
- Make the driver accept SPI_MODE_3
--- Yi Li 2008-12-01 23:16:02
fixed and close the bug.
Next step would be:
- Wait and hope mainline accept changes in mmc_spi.c
- Performance testing
...
Files
Changes
Commits
Dependencies
Duplicates
Associations
Tags
File Name File Type File Size Posted By
stamp.c.diff application/octet-stream 1077 Hans Eklund
mmc_spi.c.diff application/octet-stream 2794 Hans Eklund