[#3991] mmc_spi not working out of the box.

Document created by Aaronwu Employee on Aug 28, 2013
Version 1Show Document
  • View in full screen mode

[#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

Attachments

    Outcomes