Hi all, 2011/11/3 馬克泡 <macp...@gmail.com>: > Hi all, > > I have a problem on reading low speed card on my platform. > While high speed card were all correct.
I've reported a problem with FTSDC010 controller last week. The problem is, when I'm using card SD ver 1.10 on the platform, the hardware will report CRC_FAIL when doing DATA transaction when it reads more then 1 block (512bytes). After debugging into the problem, I found that if force the high speed card (capability) under low speed mode, the CRC_FAIL problem won't occur. But, the high speed card which is SD ver 2.0 and later won't have this kind of problem. However, after I've got the SD 3.0 specification this week. I've checked CSD information and SD_SWITCH_SWITCH (STATUS) information with the card I've read. The detecting function of high_speed seems no problem at all. But controller still report CRC_FAIL when the hardware is doing DATA transaction. Some cards will even worse, the hardware will report CRC_FAIL on SD_SWITCH_CHECK Command. After comparing to the Linux generic mmc stack. I've found that when the mmc stack is setting ios (clock) of the card, even if the card reported it has high speed capability (SW_SWITCH_STATUS >50Mhz), the mmc stack will still check the tran_speed (CSD) recorded in mmc card. However, the u-boot's mmc stack will only check if the clock is smaller than f_max (this should be the capability of mmc host controller, correct?) but not the actual speed of the card. The following is the part of Linux code, "drivers/mmc/core/sd.c", mmc_sd_init_card(). /* * Compute bus speed. */ max_dtr = (unsigned int)-1; if (mmc_card_highspeed(card)) { if (max_dtr > card->sw_caps.hs_max_dtr) { max_dtr = card->sw_caps.hs_max_dtr; printk(KERN_WARNING "%s: sw_caps.hs_max_dtr compute bus speed: %08x\n", __func__, card->sw_caps.hs_max_dtr); } } else if (max_dtr > card->csd.max_dtr) { max_dtr = card->csd.max_dtr; printk(KERN_WARNING "%s: csd.max_dtr compute bus speed: %08x\n", __func__, card->csd.max_dtr); } mmc_set_clock(host, max_dtr); The following is the u-boot code, "drivers/mmc/mmc.c", mmc_startup(). if (IS_SD(mmc)) { [snip] if (mmc->card_caps & MMC_MODE_HS) mmc_set_clock(mmc, 50000000); else { mmc_set_clock(mmc, 25000000); The stack will set 50Mhz as the value of the clock to the driver if MMC_MODE_HS has been detected. The MODE_HS detecting function are most the same in both Linux's and u-boot's code. In my case, the capability of the platform can support clock up to 33000000MHz, which is depended to the AHBBUS_CLOCK. I'm going to add a piece of code to like the behavior in the Linux. Please help on comments. Thanks! -- Best regards, Macpaul Lin _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot