--- cpu/at32ap7xxx/mmc.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) Index: u-boot-1.1.4-avr32/cpu/at32ap7xxx/mmc.c =================================================================== --- u-boot-1.1.4-avr32.orig/cpu/at32ap7xxx/mmc.c 2007-01-30 14:53:33.000000000 +0100 +++ u-boot-1.1.4-avr32/cpu/at32ap7xxx/mmc.c 2007-01-30 15:45:37.000000000 +0100 @@ -67,6 +67,7 @@ struct mmci { unsigned int rca; block_dev_desc_t blkdev; const struct device *dev; + int card_is_sd; }; struct mmci mmci = { @@ -391,6 +392,8 @@ static int sd_init_card(struct mmci *mmc mmc->rca = resp[0] >> 16; if (verbose) printf("SD Card detected (RCA %u)\n", mmc->rca); + mmc->card_is_sd = 1; + return 0; } @@ -425,6 +428,57 @@ static int mmc_init_card(struct mmci *mm return ret; } +static void mci_set_data_timeout(struct mmci *mmc, struct mmc_csd *csd) +{ + static const unsigned int dtomul_to_shift[] = { + 0, 4, 7, 8, 10, 12, 16, 20, + }; + static const unsigned int taac_exp[] = { + 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, + }; + static const unsigned int taac_mant[] = { + 0, 10, 12, 13, 15, 60, 25, 30, + 35, 40, 45, 50, 55, 60, 70, 80, + }; + unsigned int timeout_ns, timeout_clks; + unsigned int e, m; + unsigned int dtocyc, dtomul; + u32 dtor; + + e = csd->taac & 0x07; + m = (csd->taac >> 3) & 0x0f; + + timeout_ns = (taac_exp[e] * taac_mant[m] + 9) / 10; + timeout_clks = csd->nsac * 100; + + timeout_clks += (((timeout_ns + 9) / 10) + * ((CFG_MMC_CLK_PP + 99999) / 100000) + 9999) / 10000; + if (!mmc->card_is_sd) + timeout_clks *= 10; + else + timeout_clks *= 100; + + dtocyc = timeout_clks; + dtomul = 0; + while (dtocyc > 15 && dtomul < 8) { + dtomul++; + dtocyc = timeout_clks >> dtomul_to_shift[dtomul]; + } + + if (dtomul >= 8) { + dtomul = 7; + dtocyc = 15; + puts("Warning: Using maximum data timeout\n"); + } + + dtor = (MMCI_MKBF(MCI_DTOR_DTOMUL, dtomul) + | MMCI_MKBF(MCI_DTOR_DTOCYC, dtocyc)); + mmci_writel(&mmci, MCI_DTOR, dtor); + + printf("mmc: Using %u cycles data timeout (DTOR=0x%x)\n", + dtocyc << dtomul_to_shift[dtomul], dtor); +} + int mmc_init(int verbose) { struct mmc_cid cid; @@ -443,6 +497,8 @@ int mmc_init(int verbose) mmci_writel(&mmci, MCI_IDR, ~0UL); mci_set_mode(CFG_MMC_CLK_OD, CFG_MMC_BLKLEN); + mmci.card_is_sd = 0; + ret = sd_init_card(&mmci, &cid, verbose); if (ret) { mmci.rca = MMC_DEFAULT_RCA; @@ -458,6 +514,8 @@ int mmc_init(int verbose) if (verbose) mmc_dump_csd(&csd); + mci_set_data_timeout(&mmci, &csd); + /* Initialize the blockdev structure */ sprintf(mmci.blkdev.vendor, "Man %02x%04x Snr %08x",