2008-11-18 09:37:30     The SD card / SPI blues..

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

2008-11-18 09:37:30     The SD card / SPI blues..

Wolfgang Muees (GERMANY)

Message: 65443   

 

Hi,

 

in my current project, I am working with a BF52x.  Part of the requirement is a SD Card interface with SPI.

 

In the current Blackfin uclinux tree, there are 2 different drivers for SD cards over SPI. One is part of the mmc framework and works with every SPI master driver (CONFIG_MMC_SPI). The other one is a standalone block device (CONFIG_SPI_MMC).

 

The standalone driver is the one which is used in most blackfin projects.  IMHO, I see no great value in doing-it-all-standalone and to put aside the previous work of the community in the MMC framework. There are many posts from users which have problems with this driver.

 

So I decided to give the mmc_spi driver a chance.

 

First of all I found that CONFIG_SPI_MMC has made a chip select reservation in the platform data structure in the board setup file (ezkit.c). So I had to disable CONFIG_SPI_MMC in the kernel konfiguration and follow the highlander way.

 

Second, I discovered that the SPI master driver (spi_bf5xx.c) set CS=HIGH between every transmitted word. This is a flaw in the SPI hardware, and IMHO, the SPI master driver should use the CS as GPIO if continuous transfer is specified. As the SD card interface is working with either SPI mode 0 or 3, I made a little patch to mmc_spi.c to accept an SPI_MODE == 3 from the platform data structures.

 

Inserting a SD card and reading from the SD card was working fine now. But every write cycle fails. I discovered that there is a fundamental bug in the Blackfin SPI master driver (spi_bf5xx.c). Every word transfer is bidirectional: for each transmitted word, one word is received and stays in the read buffer. So if I have a write (e.g. writing SD card sector data), and this write is followed by a duplex transfer (e.g. reading the response from the SD card while transmitting 0xFFs), the first read of the duplex transfer returned an old value from the read buffer. My fix was to empty the read buffer before each duplex transfer. There may be better ways of dealing with this problem, but this one is fast and save.

 

Now, reading and writing to SD cards is working like a charm. The MMC framework supports SDHC cards too, and I wrote a few lines for the busybox MDEV system to automount the SD cards.

 

All I have to do as system startup time is to load the modules:

 

insmod auer_sdspires.ko

modprobe mmc_block

modprobe mmc_spi

 

auer_sdspires.c contains the glue logic which is needed to connect the mmc/spi framework with the hardware. You may use it as a template for your own implementation.

 

The required patches and files are appended here. Will someone of the Blackfin developers merge them and push them upstream, or should I try to do this?

 

Best regards

 

Wolfgang

 

mmc_spi.patch

mdev.conf

auer_sdspires.c

spi_bfin5xx.patch

hotplug-sd

TranslateQuoteReplyEditDelete

 

 

2008-11-18 09:58:03     Re: The SD card / SPI blues..

Mike Frysinger (UNITED STATES)

Message: 65446   

 

you didnt read the posts quite cleary enough.  the problem is not in a specific driver, the problem is with the MMC/SD protocol and limitations in the common SPI framework.  it doesnt matter what implementation of the MMC/SD driver you pick, you're going to hit the same problem.

 

the Blackfin SPI master driver respects the cs_change settings.  if your resources / transfer structure is not declaring it properly, then that is a bug in your code, not the master driver.  that said, you should test the latest 2008R1.5 branch as the master driver has fixed a few bugs when using multiple devices simultaneously.

 

the comment about platforms not supporting mode 0 seems pretty dubious ... the Blackfin SPI controller supports all modes.

QuoteReplyEditDelete

 

 

2008-11-18 10:46:31     Re: The SD card / SPI blues..

Wolfgang Muees (GERMANY)

Message: 65447   

 

Hello Mike,

 

thank you for your fast reply, and to correct my formatting problem in the first post.

 

You wrote:

the Blackfin SPI master driver respects the cs_change settings.  if your resources / transfer structure is not declaring it properly, then that is a bug in your code, not the master driver.

 

Nope, that's simply not true. With SPI_MODE == 0, I get a CS == HIGH between each transfer. Simply setting SPI_MODE to 3 (without changing anything other!) cured the problem.

 

The observed behaviour is consistent with the Blackfin Hardware Reference Manual Vol. 2, Page 22-15. I assume that for non-dma transfers, "one transfer" is equal to "one word" (from the point of the SPI hardware). Do you have proven test cases for the SPI master driver which allows SPI_MODE == 0 and CS staying active? Can you post the test case that we can compare the settings?

that said, you should test the latest 2008R1.5 branch as the master driver has fixed a few bugs when using multiple devices simultaneously.

 

I have updated the SPI master driver to SVN. I do not talk about using multiple devices simultaneously. I know about the locking issue. This is not my problem. The SPI device is only used by the SD card driver.

 

best regards

 

Wolfgang

TranslateQuoteReplyEditDelete

 

 

2008-11-18 11:13:22     Re: The SD card / SPI blues..

Mike Frysinger (UNITED STATES)

Message: 65448   

 

if you're seeing SPI misbehavior, then open a tracker item describing the exact issue

QuoteReplyEditDelete

 

 

2008-11-18 21:28:20     Re: The SD card / SPI blues..

Yi Li (CHINA)

Message: 65467   

 

Inserting a SD card and reading from the SD card was working fine now. But every write cycle fails. I discovered that there is a fundamental bug in the Blackfin SPI master driver (spi_bf5xx.c). Every word transfer is bidirectional: for each transmitted word, one word is received and stays in the read buffer. So if I have a write (e.g. writing SD card sector data), and this write is followed by a duplex transfer (e.g. reading the response from the SD card while transmitting 0xFFs), the first read of the duplex transfer returned an old value from the read buffer. My fix was to empty the read buffer before each duplex transfer. There may be better ways of dealing with this problem, but this one is fast and save.

 

Now, reading and writing to SD cards is working like a charm. The MMC framework supports SDHC cards too, and I wrote a few lines for the busybox MDEV system to automount the SD cards.

 

...

 

The required patches and files are appended here. Will someone of the Blackfin developers merge them and push them upstream, or should I try to do this?

 

---

 

Hi Wolfgang,

 

This is great.  I am troubled by the duplex R/W failured of mmc_spi driver for a long time (and I have to re-write mmc_spi driver to not to use duplex transfer). I will test your patch. Thanks.

 

-Yi

QuoteReplyEditDelete

 

 

2008-11-19 03:20:05     Re: The SD card / SPI blues..

Yi Li (CHINA)

Message: 65477   

 

if you're seeing SPI misbehavior, then open a tracker item describing the exact issue

 

---

 

Wolfgang,

 

If I understand your description clearly, you mean mmc_spi driver works in both SPI_MODE_0 (i.e, CPOL =0 && CPHA = 0) and SPI_MODE_3 (i.e, CPOL=1 && CPHA = 1). And yes, this is what I observed.

 

You think SPI_MODE_3 should be better since CS stay asserted between each transferred words (if chip->cs_change_per_word == 0). And I agree with this.

 

Also as you mentioned, in SPI_MODE_0, CS goes deasserted between transferred words, which conforms with the HRM.

 

So there is no SPI HW issue / disagreement with regard to CPHA, isn't it?

 

For the duplex patch, I tested with a SD card and a SDHC card, both work great! I got initialization error when using a mmc card and I am debugging it on my side. Thanks again for the patch.

 

-Yi

 

 

QuoteReplyEditDelete

 

 

2008-11-19 06:18:18     Re: The SD card / SPI blues..

Yi Li (CHINA)

Message: 65516   

 

When turned on CONFIG_MMC_DEBUG, sometimes there would be "ETIMEDOUT" error (in mmc_spi_readblock()) when initializing MMC card  . If turn off the debug option, mmc card works well. So it should not be a big issue.

 

I am doing R/W big files to have more test.

 

-Yi

QuoteReplyEditDelete

 

 

2008-11-19 10:19:27     Re: The SD card / SPI blues..

Wolfgang Muees (GERMANY)

Message: 65551   

 

Yi Li,

 

I have spend one more day debugging the SD card / SPI driver.

 

I have found 2 places in the mmc_spi driver where the real card was sometimes slower than the actual SD card standard.

 

This results in TIMEOUT messages.

 

And I have found another problem in the SPI host controller driver: after a write, the very first character of the response was missing. I think it may be due to a TX buffer overwrite. I have added code to check for not overwrite the TX buffer, and the problem has disappeared.

 

I have added a line to mdev.conf to mount SD cards with partitions (SDHC).

 

There are issues with SDHC cards remaining... I got a bad CRC on read, and write errors/timeouts (only after a while, maybe the SDHC controller was busy internal and the software has not recognized it).

 

 

Patches and files are added to this text.

 

regards

 

Wolfgang

 

mdev.conf

spi_bfin5xx_2.patch

mmc_spi_2.patch

TranslateQuoteReplyEditDelete

 

 

2008-11-20 02:50:22     Re: The SD card / SPI blues..

Yi Li (CHINA)

Message: 65575   

 

Wolfgang,

 

1. For the mmc_spi TIMEOUT patch, what is the card you are using? I will see if I can reproduce this problem. Since it is kind of a hack to the SD spec, I am not sure the mainline kernel would accept that.  We can try to push the patch upsteam, but maybe you can also post the patch to LKML and spi-devel list.

 

2. For spi_bfin5xx_2.patch, could you give more details on the error? I tested with my STAMP board for R/W on SD/MMC card for a whole day(after using the duplex patch), it looks not error happens yet. Also, looking at spi_bfin5xx.c, at the end of each write, there will be check of SPIF to make sure transfer finished.

 

"    /* poll for SPI completion before return */

    while (!(read_STAT(drv_data) & BIT_STAT_SPIF))

        cpu_relax();"

 

Checking of TXS before each write looks not necessary.

 

"

 

+        /* wait until TDBR is empty from last transfer */

+        while ((read_STAT(drv_data) & BIT_STAT_TXS))

+                cpu_relax();

 

"

 

3. I have also observed write errors using a 8GB Transcend SDHC card (class 6).

 

Thanks,

 

-Yi

QuoteReplyEditDelete

 

 

2008-11-20 05:14:00     Re: The SD card / SPI blues..

Wolfgang Muees (GERMANY)

Message: 65584   

 

Yi,

 

1. For the mmc_spi TIMEOUT patch, what is the card you are using?

This was a noname 1 GB SD card.

 

Since it is kind of a hack to the SD spec, I am not sure the mainline kernel would accept that.

 

Why not? The SD spec is for the Cards. If the host uses more relaxed timeout values, it's not a spec violation. And the timeout values in the mmc_spi driver are for SD cards. What if MMC cards using a slower timing?

 

IMHO, the host driver should use timeout values which allowes any card to operate. Using long timeout will not lead to a slower interface if you use fast cards.

 

2. For spi_bfin5xx_2.patch, could you give more details on the error?

 

Yes. One rare occasions, I got errors on reading the data response token after a sector write operation. From the observed behaviour, it seems that I got off-by-one-errors between TX and RX. Doing a code review, the writing of the first TX byte without waiting for TXS was the only odd behaviour I can find. I fixed this, and my off-by-one errors disappeared.

 

I tested with my STAMP board for R/W on SD/MMC card for a whole day(after using the duplex patch), it looks not error happens yet.

 

Hm. This error was rare, and may only reveal under certain combinations of CPU clock and SPI clock. I am using a BF526 Rev. 0.0 at 300 MHz and SPI with 20 MHz.

 

Also, looking at spi_bfin5xx.c, at the end of each write, there will be check of SPIF to make sure transfer finished.

 

"    /* poll for SPI completion before return */

    while (!(read_STAT(drv_data) & BIT_STAT_SPIF))

        cpu_relax();"

 

Checking of TXS before each write looks not necessary.

 

Do you know the exact relationship between TXS and SPIF? The relation of RXS and SPIF is dependent on the clock divider in the SPI BAUD register. Maybe something similar is true for TXS and SPIF?

 

By the way: the handling of the last READ byte (using the SHADOW register) is a little bit fishy too.. reading from SHADOW does not clear the RXS flag...

 

3. I have also observed write errors using a 8GB Transcend SDHC card (class 6).

 

The same is true for me! The most interesting thing about this is that it is NEVER the first write which fails. The failure only occurs after some writes are done. So I expect that there is a BUSY condition from the SHDC card which is not obeyed by the MMC/SPI framework.

 

best regards

 

Wolfgang

TranslateQuoteReplyEditDelete

 

 

2008-11-21 04:17:27     Re: The SD card / SPI blues..

Wolfgang Muees (GERMANY)

Message: 65676   

 

I think I have found the cause of the outstanding read/write errors: The response time is not an integral number of bytes, but instead starts in the middle of a transfered byte. I will have a look at the mmc_spi driver to fix that.

 

 

TranslateQuoteReplyEditDelete

 

 

2008-11-21 04:52:16     Re: The SD card / SPI blues..

Yi Li (CHINA)

Message: 65677   

 

Good news. Hoping to see your fix soon.

QuoteReplyEditDelete

 

 

2008-11-21 06:21:19     Re: The SD card / SPI blues..

Yi Li (CHINA)

Message: 65680   

 

If the mmc_spi driver finally works OK on blackfin, I am going to test it to share bus with other SPI devices. (We' ve added  spi_lock_bus() and spi_unlock_bus() APIs for exclusive access). Also some people complain that the R/W speed is slow using old spi_mmc driver. So some performance test is also necessary.

 

-Yi

QuoteReplyEditDelete

 

 

2008-11-21 08:29:25     Re: The SD card / SPI blues..

Wolfgang Muees (GERMANY)

Message: 65683   

 

OK,

 

seems that I finaly got it ;-)

 

I have made many test with both the SPI master driver and the mmc_spi driver.

 

For the SPI master driver (spi_bfin5xx.c), I tried to unify all non-dma-transfer functions to one TIMOD, because I want to have exactly the same conditions for each transfer type (read/write/duplex) change. Initialy, I have used TIMOD=00, but in this mode, I failed to setup TDBR prior to the transfer (data value was not shifted out). So I used SPI_WRITE, and all is OK. Hmmm. Maybe the Blackfin SPI hardware designer has not written a device driver in his whole life?

 

Here is the changelog of spi_bfin5xx.c:

 

- Rewrite of the non-dma data transfer functions to use only ONE mode for TIMOD, so there are no special and hard to verify considerations if transfer mode (read/write/duplex) is changed.

- Avoiding TIMOD=00, because I did not manage to get the TDBR register loaded and shifted out on BF-526. Huh? Chip Errata?

- Optimise data transfer functions to minimize the delay between each byte/word transfer. This is a major source of speed limitation.

 

For the MMC SPI driver, I have done lot of instrumentation in the code to find the cause of misbehaviour with certain types of SD cards. Here is the changelog:

 

- 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(!).

 

With these modifications, both SD and SDHC cards are working fine now. Note that I have seen page allocation errors in MDEV (insert card, automount, write to card, sync, remove card, wait a few seconds) which seem to be totaly unrelated to mmc and spi and maybe an error in mdev or in the shell. The same is reported in this forum for usb sticks.

 

The appended patches build on the patches I send before. Feel free to send them upstream.

 

Signed-off-by: Wolfgang Muees [wolfgang.mues@auerswald.de]

 

best regards

 

Wolfgang

 

spi_bfin5xx_3.patch

mmc_spi_3.patch

TranslateQuoteReplyEditDelete

 

 

2008-11-21 09:25:43     Re: The SD card / SPI blues..

Wolfgang Muees (GERMANY)

Message: 65687   

 

Yi,

 

you wrote:

 

If the mmc_spi driver finally works OK on blackfin, I am going to test it to share bus with other SPI devices. (We' ve added  spi_lock_bus() and spi_unlock_bus() APIs for exclusive access).

 

This will be fine. Please take care that the lock is not held the whole time the mmc_spi driver is busy waiting.

 

Also some people complain that the R/W speed is slow using old spi_mmc driver. So some performance test is also necessary.

 

There are several sources of speed limitation here:

 

a) max. SPI clock is SCLK/4. So for my BF526, it's 20 MHz max.

 

b) For non-DMA cycles (each duplex cycle is non-DMA, because the blackfin SPI only has one DMA engine), there is a small but unavoidable delay between each byte transfer, so that the true mean clock rate maybe only 15 MHz for me.

 

c) Transfers are scheduled in tasklets. If the system is not idle, there are delays between each transfer which might be longer than expected... you may want to execute some tests for this problem.

 

d) Speed tests revealed that a major cause of slow reading/writing speed on SD cards is the number of blocks which are transfered at once with MULTIPLE_BLOCK_READ/WRITE. Suppose you have a 1 MByte file you want to write, and the SD card is formatted with FAT32 (4 KByte clustersize), the vfat filesystem driver will issue multiple requests of 4 KByte each. This is near to nothing and far from perfect. In one of my block drivers I have wrote for another project, I have implemented a private I/O scheduler which makes bigger requests out of small ones. (More than 64 KByte at once gives no difference).

 

e) The mmc_spi driver uses a lot of duplex transfers, because it's the requirement to send 0xFF when reading a block of data. The SPI framework is sending 0x00 for read requests. If the SPI framework can be extended to specify the value to send out in a read request, many duplex requests can be changed to read requests, and can use DMA.

 

regards

 

Wolfgang

TranslateQuoteReplyEditDelete

 

 

2008-11-22 06:18:52     Re: The SD card / SPI blues..

Wolfgang Muees (GERMANY)

Message: 65719   

 

Yi,

 

forget the e) case (DMA). This will not be usable due to the SPI-DMA-doesnt-stop bug.

 

When will Analog Devices rework the SPI interface? I can't imagine they want to live forever with this ****.

 

best regards

 

Wolfgang

TranslateQuoteReplyEditDelete

 

 

2008-11-22 16:29:22     Re: The SD card / SPI blues..

Eduardo Tagle (ARGENTINA)

Message: 65723   

 

Hi... I am myself also working on the DMA-SPI problem ... I have to store the root file system on a SD card, so it's also extremely important to me to make the mmc_spi driver work as perfect as possible, and also try as much as possible to use DMA to read from and write to the MMC (polling the SPI is not exactly the best thing to do here, as it eats too much cpu cycles ... ). I have already added interrupt driven SPI transfers to the spi driver, but i won't release it until i can really test it ... That will be, i estimate, about mid-december ... because i don't have the hw right now

 

I have read here and on several other posts that using DMA is not possible to exactly read an specified count of bytes ... because spi clk does not stop when the last word to be read (according to the x_count DMA register) is read.. And, that due to the interrupt processing latency, there's no workaround for that... BUT ... perhaps there's a way... i came accros this   www.blackfin.org/phorum/read.php?12,7408 post, extremely interesting reading, by the way... seems there's a way to use DMA to read/write into a MMC.

 

Hope it can help

 

 

TranslateQuoteReplyEditDelete

 

 

2008-11-22 16:32:42     Re: The SD card / SPI blues..

Eduardo Tagle (ARGENTINA)

Message: 65724   

 

PD> Of course i will try this myself... i posted it because i think it was very interesting and relates to the problems being discussed here.

TranslateQuoteReplyEditDelete

 

 

2008-11-24 02:17:18     Re: The SD card / SPI blues..

Yi Li (CHINA)

Message: 65736   

 

>For the MMC SPI driver, I have done lot of instrumentation in the code to find the cause of misbehaviour with >certain types of SD cards. Here is the changelog:

 

>- 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(!).

 

---

 

Wolfgang,

 

I am wondering what is your mmc_spi.c driver revision? (are you using code from svn trunk on blackfin.uclinux.org or the mainline kernel)? It looks the mmc_spi.c patch is not based on latest driver. Here the svn log shows there has been changes for the "timeout" code in svn trunk. Could you please update the patch?

 

Thanks,

 

-Yi

 

svn diff -r 5114:5502 mmc_spi.c

Index: mmc_spi.c

===================================================================

--- mmc_spi.c    (revision 5114)

+++ mmc_spi.c    (revision 5502)

@@ -95,8 +95,6 @@

  * reads which takes nowhere near that long.  Older cards may be able to use

  * shorter timeouts ... but why bother?

  */

-#define readblock_timeout    ktime_set(0, 100 * 1000 * 1000)

-#define writeblock_timeout    ktime_set(0, 250 * 1000 * 1000)

#define r1b_timeout        ktime_set(3, 0)

 

 

@@ -220,9 +218,9 @@

     return mmc_spi_skip(host, timeout, sizeof(host->data->status), 0);

}

 

-static int mmc_spi_readtoken(struct mmc_spi_host *host)

+static int mmc_spi_readtoken(struct mmc_spi_host *host, ktime_t timeout)

{

-    return mmc_spi_skip(host, readblock_timeout, 1, 0xff);

+    return mmc_spi_skip(host, timeout, 1, 0xff);

}

 

[snip]

 

QuoteReplyEditDelete

 

 

2008-11-24 05:33:07     Re: The SD card / SPI blues..

Yi Li (CHINA)

Message: 65754   

 

Wolfgang,

 

I tested the latest patch on BF537 STAMP (running at 500MHz/100MHz). I noticed that write speed of SDHC is much slower than SD. Writing a 4.7MB file to SDHC card takes 60 seconds, while writing to SD card takes 25 seconds. Is this a card issue or driver issue?

 

-Yi

 

SDHC:

 

root:/> mount -o sync /dev/mmcblk0p1 /mnt/  

root:/> ls -l /mnt/test.pdf                                                   

-rwxr-xr-x    1 root     root      4938567 Jan  1 05:56 /mnt/test.pdf                                                                                                       

root:/> time cp /mnt/test.pdf /var/                                           

real    0m 6.24s                                                              

user    0m 0.02s                                                              

sys     0m 0.37s                                                              

root:/> time cp /var/test.pdf /mnt/                                           

real    1m 0.80s                                                              

user    0m 0.02s                                                              

sys     0m 1.30s                                                              

root:/> time cp /var/test.pdf /mnt/                                           

real    1m 4.33s                                                              

user    0m 0.02s                                                              

sys     0m 1.31s                                                              

       

 

SD:

 

                                                   

root:/> mount -o sync /dev/mmcblk1p1 /mnt/                                    

root:/> time cp /mnt/test.pdf /var/                                           

real    0m 6.11s                                                              

user    0m 0.02s                                                              

sys     0m 0.34s                                                              

root:/> time cp /var/test.pdf /mnt/                                           

real    0m 24.21s                                                             

user    0m 0.02s                                                              

sys     0m 1.00s                                                              

root:/> time cp /var/test.pdf /mnt/                                           

real    0m 25.56s                                                             

user    0m 0.04s                                                              

sys     0m 1.10s

QuoteReplyEditDelete

 

 

2008-11-24 05:55:54     Re: The SD card / SPI blues..

Wolfgang Muees (GERMANY)

Message: 65755   

 

Yi,

 

yes, I am not working on the svn trunk, but on kernel 2.6.26.

 

 

I have prepared my patches to be applied to the svn kernel (see appended files) All changes in one patch.

 

Write speed tests:

 

- mounting with -o sync is slow. You should do tests with and without sync mount.

 

- the SDHC card has a bigger internal blocksize. I assume the card is formatted with FAT 32 and clustersize = 4K. The SDHC card may have a blocksize of 16K or more. So the card will have to do partial block writes, which gives you a slow and fast-wearing-out behaviour.

 

IMHO it is time to implement some sort of block combining in drivers/mmc/core/block.c.

 

best regards

 

Wolfgang

 

mmc_spi.diff

spi_bfin5xx.diff

TranslateQuoteReplyEditDelete

 

 

2008-11-25 05:37:39     Re: The SD card / SPI blues..

Yi Li (CHINA)

Message: 65782   

 

Wolfgang,

 

I posted the spi_bf5xx.diff to uclinux-dist-devel mailing list for review by other developers. For mmc_spi.diff,

 

"unsigned long timeout_jiffies = (unsigned long)((ktime_to_us(timeout) * HZ) / 1000000);"

 

Will cause "ERROR: "__divdi3" [drivers/mmc/host/mmc_spi.ko] undefined!" since it uses 64-bit division.

 

Regards,

 

-Yi

QuoteReplyEditDelete

 

 

2008-11-25 06:43:55     Re: The SD card / SPI blues..

Wolfgang Muees (GERMANY)

Message: 65784   

 

Yi,

 

For mmc_spi.diff,

 

"unsigned long timeout_jiffies = (unsigned long)((ktime_to_us(timeout) * HZ) / 1000000);"

 

Will cause "ERROR: "__divdi3" [drivers/mmc/host/mmc_spi.ko] undefined!" since it uses 64-bit division.

 

Damned,

 

I have not tested this patch - because my environment is stuck at kernel 2.6.26, and the mmc_spi.c from svn does not compile in kernel 2.6.26.

 

The whole ktime.h with the inherent 64 bit length is IMHO a very bad implementation because there is a lack of functions for comparing 2 numbers (the only compare function is EQUAL). So I could not use ktime_t inside the wait loop.

 

Could you please test with:

 

struct timeval tv = ktime_to_timeval(timeout);

 

unsigned long timeout_jiffies = tv.tv_sec * HZ +  (tv.tv_usec * HZ) / USEC_PER_SEC;

 

best regards

 

Wolfgang

TranslateQuoteReplyEditDelete

 

 

2008-11-26 05:28:00     Re: The SD card / SPI blues..

Yi Li (CHINA)

Message: 65840   

 

It is OK this time. Thanks.

 

-Yi

QuoteReplyEditDelete

 

 

2008-11-26 06:44:05     Re: The SD card / SPI blues..

Wolfgang Muees (GERMANY)

Message: 65844   

 

Yi,

 

my tests shows that the write speed to SD cards is about 500-600 KByte/sec.

 

The read speed is about 800 KByte/sec. (This is on a FAT16 microSD card with 2 GBytes from Sandisk).

 

This is without the -o sync option. If you mount a SD card with -o sync, you will have a fast wear-out of the sectors which hold the file allocation table, and the SD card will get unusable in a very short time.

 

regards

 

Wolfgang

 

 

TranslateQuoteReplyEditDelete

 

 

2008-12-04 11:26:20     Re: The SD card / SPI blues..

Wolfgang Muees (GERMANY)

Message: 66358   

 

Hi,

 

I have tested some more SD cards now... and changed my BF526 @ 300 MHz to a BF 527 @ 530 MHz.

 

I found no more issues with the spi_bfin5xx driver .. all fine here now.

 

However, there are some SD cards here out in the wild that do not comply to the SD card specification and do not work with the mmc_spi driver.

 

I have tested a 1 GB Kingston SD card which has a response time between command and response which is NOT byte-aligned. I have not found an easy way to fix this problem, because the missalignment remains for the whole rest of the transfer, including the data block transfer. To support these ill-designed SD cards, the mmc_spi driver needs a major rework.

 

I have tested a 8 GByte noname SDHC card which does send the CID with a crippled CRC-16 appended. I do not know how common this error is... I have disabled CRC checking for the mmc_spi driver. There is a command line parameter while loading the mmc core module:

 

modprobe mmc_core use_spi_crc=0

 

 

best regards

 

Wolfgang

TranslateQuoteReplyEditDelete

 

 

2008-12-04 23:35:27     Re: The SD card / SPI blues..

Yi Li (CHINA)

Message: 66370   

 

Wolfgang,

 

So it looks hacks for specific card are necessary in mmc_spi.c, maybe it is better to add some CONFIG_* options to deal with those special cases?

 

Another issue is, we know that if enabled dma, data block write will be done in DMA mode. But data block read will not since it uses duplex transfer. We have updated the SPI dma code hoping it is more stable and we think it is better to use SPI DMA whenever possible. I've tested mmc_spi driver with dma enabled, until now data block write works OK. I also tried to make data block read use DMA:

 

===================================================================

--- mmc_spi.c    (revision 5811)

+++ mmc_spi.c    (working copy)

@@ -545,8 +545,10 @@

      */

     t = &host->t;

     memset(t, 0, sizeof(*t));

+#ifdef MMC_SPI_DATA_DUPLEX

     t->tx_buf = host->ones;

     t->tx_dma = host->ones_dma;

+#endif

     /* length and actual buffer info are written later */

     spi_message_add_tail(t, &host->m);

 

 

However the CRC bits following that data block are not correct. There must be something I don't understand.

 

Regards,

 

-Yi

QuoteReplyEditDelete

 

 

2008-12-05 03:29:40     Re: The SD card / SPI blues..

Wolfgang Muees (GERMANY)

Message: 66381   

 

Yi,

 

So it looks hacks for specific card are necessary in mmc_spi.c

 

Yes. There are MANY cards which don't conform to the SD card spec. If you look at commercial SD/FAT drivers, you will find they all allow for response times which are not a multiple of 8 bits. In this case, you need to parse the received data stream, bit-shift and combine. Forget about performance! I think you can imagine that the existing drivers (may it be mmc_spi or spi_mmc) are not designed to do such a thing.

 

For the CRC error in reading the CID register, it may be the best fix to discard read CRC if len != 512. So you only get CRC disabled for non-data-blocks. And the CID register is protected be an own CRC7 checksum.

 

You may check for t->len != MMC_SPI_BLOCKSIZE in the last part of mmc_spi_readblock().

 

maybe it is better to add some CONFIG_* options to deal with those special cases?

 

CONFIG options are not the right way to go. Remember, the builder of an embedded device do not know which SD cards are used by the customer. The best thing to do is to code a driver which is able to cope with all SD cards in the world. Performance may suffer - but only for the bad cards, not for the good.

 

I've tested mmc_spi driver with dma enabled, until now data block write works OK.

 

This is good news, and it's what I have expected. Does DMA write gives you more performance? I suspect that the performance gain is little because of the protocol elements which must be handled in software (CRC, block starts, data tokens etc).

 

Read: However the CRC bits following that data block are not correct. There must be something I don't understand.

 

This is the expected behaviour because of the read DMA bug of the blackfin SPI hardware. This is covered in this thread:   www.blackfin.org/phorum/read.php?12,7408

 

IMHO, there is no way around it... it MIGHT be possible if you only use single data block read, but single data block read is SO SLOW that you would gain nothing from DMA. For multiple block reads, you likely miss the start of the next data block, because they are coming back-to-back.

 

Do you have asked the hardware guys at analog devices when they will fix the SPI/DMA issue?

 

best regards

 

Wolfgang

TranslateQuoteReplyEditDelete

 

 

2009-01-06 08:31:23     Re: The SD card / SPI blues..

Wolfgang Muees (GERMANY)

Message: 67472   

 

Appended is the small patch to support SD(HC) cards which are not able to supply a valid CRC for CID reads.

 

This patch is neccessary if you include the mmc_spi driver in the kernel image.

 

best regards

 

Wolfgang

 

 

 

spi_mmc_nocrc.patch

TranslateQuoteReplyEditDelete

 

 

2009-03-11 09:51:26     Re: The SD card / SPI blues..

Wolfgang Muees (GERMANY)

Message: 70777   

 

Hi,

 

I have reworked my patches and submitted them to the linux kernel mailing list for inclusion.

 

One last patch adds support for those ugly "1 GByte Kingston SD cards" which - among others - are sending their data and responses non-byte-aligned.

 

best regards

 

Wolfgang

 

 

 

 

 

mmc_patch7_unaligned_responses

TranslateQuoteReplyEditDelete

 

 

2009-03-11 21:40:16     Re: The SD card / SPI blues..

Yi Li (CHINA)

Message: 70800   

 

Wolfgang,

 

Thanks for the patch. I will have a try on my side.

 

-Yi

QuoteReplyEditDelete

 

 

2009-03-12 10:53:45     Re: The SD card / SPI blues..

Wolfgang Muees (GERMANY)

Message: 70870   

 

Two more patches for mmc appended.

 

One speedup, and a bugfix for a bug I have introduced with my earlier patches.

 

regards

 

Wolfgang

 

 

 

mmc_patch10_bugfix_of_patch3

mmc_patch9_speedup

TranslateQuoteReplyEditDelete

 

 

2009-03-16 08:46:49     Re: The SD card / SPI blues..

Wolfgang Muees (GERMANY)

Message: 71029   

 

Here is another enhancement.

 

Do propper retransmissions if there are transmission errors on the line.

 

This gives the driver the needed "rock-solid" performance for production use.

 

 

 

regards

 

Wolfgang

 

 

 

PS: I try to push all these changes into the linux kernel via lkml. Many of

 

these patches will be rewritten and small corrections made. But all of them

 

are verified in my blackfin setup with several SD cards and test cases.

 

 

 

mmc_patch11_retries

TranslateQuoteReplyEditDelete

 

 

2009-03-18 05:36:35     Re: The SD card / SPI blues..

Yi Li (CHINA)

Message: 71195   

 

Wolfgang,

 

We have a tracker open to merge your patches: https://blackfin.uclinux.org/gf/project/uclinux-dist/tracker/?action=TrackerItemEdit&tracker_id=328&tracker_item_id=4994.

 

I will track LKML and find a proper time to merge your patches before 2009R1 release.

 

Thanks again for the patches.

 

-Yi

QuoteReplyEditDelete

 

 

2009-03-18 10:40:54     Re: The SD card / SPI blues..

Wolfgang Muees (GERMANY)

Message: 71207   

 

Hi,

 

I have made a small patch to the Bfin SPI driver to do DMA only for writes (because of the read DMA non-anomaly),

 

and enabled DMA in the boards file (platform data).

 

With this setup, I have measured the following speeds.

 

 

 

SD card was the "famous" 1 GByte Kingston SD card (with non-aligned data response, each received byte must be rotated).

 

These times were measured with FAT16 and a 100 MByte File (using the vfat filesystem):

 

 

 

BF 526, 299 MHz Clock, 18,7 MHz SPI-Clock: Read 890 KBytes/Sec, Write 1100 KBytes/Sec.

 

BF 527, 529 MHz Clock, 22.0 MHz SPI-Clock: Read 1330 KBytes/Sec, Write 1575 KBytes/Sec.

 

 

 

regards

 

Wolfgang

TranslateQuoteReplyEditDelete

 

 

2009-04-02 04:55:48     Re: The SD card / SPI blues..

Yi Li (CHINA)

Message: 72027   

 

Hi Wolfgang,

 

Could you please post you patch "do DMA only for writes" here? So we can review & test it.

 

I also tried to merge your previous patches to svn trunk. I refered to the patches you posted on this thread, also the serial of patches you submitted to LKML between 2009-03-11 and 2009-0318. Result is a patch attached here: "mmc_090402.patch". I am going to check in it.

 

There is a little problem with patch "mmc_patch11_retries", it is based on linux-2.6.29, while svn trunk kernel is 2.6.28. So I only merge the "mmc_spi.c" part. Also, I did not found the post for this patch on LKML. Did I missed it?

 

Thanks,

 

-Yi

 

---

 

Recreate the patch, so it is more easy to read. Attached as mmc_090402_2.patch.

 

 

 

 

 

 

 

mmc_090402.patch

mmc_090402_2.patch

QuoteReplyEditDelete

 

 

2009-04-02 08:32:21     Re: The SD card / SPI blues..

Wolfgang Muees (GERMANY)

Message: 72042   

 

Hi Yi,

 

Could you please post you patch "do DMA only for writes" here? So we can review & test it.

 

    if (!full_duplex && drv_data->cur_chip->enable_dma

                && drv_data->len > 6) {

to

 

    if (transfer->tx_buf && !transfer->rx_buf

        && drv_data->cur_chip->enable_dma

        && drv_data->len > 6) {

 

 

in spi_bfin5xx.c. Then you can enable DMA in platform data:

 

static struct bfin5xx_spi_chip auer_sdspi_controller_data = {

        .enable_dma = 1,

        .bits_per_word = 8,

};

 

 

There is a little problem with patch "mmc_patch11_retries", it is based on linux-2.6.29, while svn trunk kernel is 2.6.28. So I only merge the "mmc_spi.c" part.

 

Hmmm... Please don't do that. The mmc_spi.c part and the block layer part are working together.

 

Also, I did not found the post for this patch on LKML. Did I missed it?

 

Getting code into the mainline kernel is hard ... pierre ossmann is only reading mail /applying changed on weekend, and so there will be several weeks gone until all patches are accepted.

 

regards

 

Wolfgang

TranslateQuoteReplyEditDelete

 

 

2009-04-23 06:36:58     Re: The SD card / SPI blues..

Michael Worcester (UNITED KINGDOM)

Message: 73094   

 

Hi, I'm also having problems using the SPI (BF537 STAMP/EZKIT) where cpu usage increases as the transfer size increase. Would it be possible for someone to actually post their "interrupt driven SPI driver" as many people seem to have written them but no-one seems to have posted them? DMA is not needed, just the driver to reduce processor load.

 

 

 

Thanks,

 

Michael.

QuoteReplyEditDelete

 

 

2009-04-23 07:28:48     Re: The SD card / SPI blues..

Yi Li (CHINA)

Message: 73100   

 

Michael,

 

I remember there is already a task tracker for this ( but I cannot find it). If you are request it, I can work on that if no one post a existing patch. But I am not sure this would drop CPU usage a lot.

 

Do you have any performance data on CPU usage?

 

-Yi

Outcomes