mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-18 21:21:37 +00:00
atmel_mci: Fix data timeout value
Calculate the data timeout based on values from the CSD instead of just using a hardcoded DTOR value. This is a backport of a similar fix in BSP 2.0, with one additional fix: the DTOCYC value is rounded up instead of down. Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
This commit is contained in:
parent
0ba8eed28b
commit
a08458303e
1 changed files with 59 additions and 0 deletions
|
@ -56,6 +56,7 @@
|
|||
#define MMC_DEFAULT_RCA 1
|
||||
|
||||
static unsigned int mmc_rca;
|
||||
static int mmc_card_is_sd;
|
||||
static block_dev_desc_t mmc_blkdev;
|
||||
|
||||
block_dev_desc_t *mmc_get_dev(int dev)
|
||||
|
@ -373,6 +374,7 @@ static int sd_init_card(struct mmc_cid *cid, int verbose)
|
|||
mmc_rca = resp[0] >> 16;
|
||||
if (verbose)
|
||||
printf("SD Card detected (RCA %u)\n", mmc_rca);
|
||||
mmc_card_is_sd = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -407,6 +409,59 @@ static int mmc_init_card(struct mmc_cid *cid, int verbose)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void mci_set_data_timeout(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;
|
||||
unsigned int shift;
|
||||
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++;
|
||||
shift = dtomul_to_shift[dtomul];
|
||||
dtocyc = (timeout_clks + (1 << shift) - 1) >> shift;
|
||||
}
|
||||
|
||||
if (dtomul >= 8) {
|
||||
dtomul = 7;
|
||||
dtocyc = 15;
|
||||
puts("Warning: Using maximum data timeout\n");
|
||||
}
|
||||
|
||||
dtor = (MMCI_BF(DTOMUL, dtomul)
|
||||
| MMCI_BF(DTOCYC, dtocyc));
|
||||
mmci_writel(DTOR, dtor);
|
||||
|
||||
printf("mmc: Using %u cycles data timeout (DTOR=0x%x)\n",
|
||||
dtocyc << shift, dtor);
|
||||
}
|
||||
|
||||
int mmc_init(int verbose)
|
||||
{
|
||||
struct mmc_cid cid;
|
||||
|
@ -421,6 +476,8 @@ int mmc_init(int verbose)
|
|||
mmci_writel(IDR, ~0UL);
|
||||
mci_set_mode(CFG_MMC_CLK_OD, MMC_DEFAULT_BLKLEN);
|
||||
|
||||
mmc_card_is_sd = 0;
|
||||
|
||||
ret = sd_init_card(&cid, verbose);
|
||||
if (ret) {
|
||||
mmc_rca = MMC_DEFAULT_RCA;
|
||||
|
@ -436,6 +493,8 @@ int mmc_init(int verbose)
|
|||
if (verbose)
|
||||
mmc_dump_csd(&csd);
|
||||
|
||||
mci_set_data_timeout(&csd);
|
||||
|
||||
/* Initialize the blockdev structure */
|
||||
mmc_blkdev.if_type = IF_TYPE_MMC;
|
||||
mmc_blkdev.part_type = PART_TYPE_DOS;
|
||||
|
|
Loading…
Add table
Reference in a new issue