diff options
-rw-r--r-- | drivers/mci/mci-core.c | 29 | ||||
-rw-r--r-- | drivers/mci/stm32_sdmmc2.c | 5 | ||||
-rw-r--r-- | include/mci.h | 25 |
3 files changed, 44 insertions, 15 deletions
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c index dd163c3d16..e5b5e8a275 100644 --- a/drivers/mci/mci-core.c +++ b/drivers/mci/mci-core.c @@ -668,10 +668,11 @@ retry_scr: static void mci_set_ios(struct mci *mci) { struct mci_host *host = mci->host; - struct mci_ios ios; - - ios.bus_width = host->bus_width; - ios.clock = host->clock; + struct mci_ios ios = { + .bus_width = host->bus_width, + .clock = host->clock, + .timing = host->timing, + }; host->set_ios(host, &ios); } @@ -996,6 +997,9 @@ static int mci_startup_sd(struct mci *mci) mci_set_bus_width(mci, MMC_BUS_WIDTH_4); } + if (mci->tran_speed > 25000000) + mci->host->timing = MMC_TIMING_SD_HS; + mci_set_clock(mci, mci->tran_speed); return 0; @@ -1021,6 +1025,8 @@ static int mci_startup_mmc(struct mci *mci) mci->tran_speed = 52000000; else mci->tran_speed = 26000000; + + host->timing = MMC_TIMING_MMC_HS; } mci_set_clock(mci, mci->tran_speed); @@ -1473,6 +1479,20 @@ static unsigned extract_mtd_year(struct mci *mci) return year; } +static const char *mci_timing_tostr(unsigned timing) +{ + switch (timing) { + case MMC_TIMING_LEGACY: + return "legacy"; + case MMC_TIMING_MMC_HS: + return "MMC HS"; + case MMC_TIMING_SD_HS: + return "SD HS"; + default: + return "unknown"; /* shouldn't happen */ + } +} + static void mci_print_caps(unsigned caps) { printf(" capabilities: %s%s%s%s%s\n", @@ -1509,6 +1529,7 @@ static void mci_info(struct device_d *dev) bw = 1; printf(" current buswidth: %d\n", bw); + printf(" current timing: %s\n", mci_timing_tostr(host->timing)); mci_print_caps(host->host_caps); printf("Card information:\n"); diff --git a/drivers/mci/stm32_sdmmc2.c b/drivers/mci/stm32_sdmmc2.c index 695e61d1cc..0c26869b03 100644 --- a/drivers/mci/stm32_sdmmc2.c +++ b/drivers/mci/stm32_sdmmc2.c @@ -631,6 +631,11 @@ static int stm32_sdmmc2_probe(struct amba_device *adev, mci_of_parse(&priv->mci); + if (mci->f_max >= 26000000) + mci->host_caps |= MMC_CAP_MMC_HIGHSPEED; + if (mci->f_max >= 52000000) + mci->host_caps |= MMC_CAP_MMC_HIGHSPEED_52MHZ; + return mci_register(&priv->mci); priv_free: diff --git a/include/mci.h b/include/mci.h index a45d744761..57a4629d12 100644 --- a/include/mci.h +++ b/include/mci.h @@ -367,6 +367,18 @@ struct mci_data { unsigned blocksize; /**< block size in bytes (mostly 512) */ }; +enum mci_timing { + MMC_TIMING_LEGACY = 0, + MMC_TIMING_MMC_HS = 1, + MMC_TIMING_SD_HS = 2, + MMC_TIMING_UHS_SDR12 = MMC_TIMING_LEGACY, + MMC_TIMING_UHS_SDR25 = MMC_TIMING_SD_HS, + MMC_TIMING_UHS_SDR50 = 3, + MMC_TIMING_UHS_SDR104 = 4, + MMC_TIMING_UHS_DDR50 = 5, + MMC_TIMING_MMC_HS200 = 6, +}; + struct mci_ios { unsigned int clock; /* clock rate */ @@ -376,17 +388,7 @@ struct mci_ios { #define MMC_BUS_WIDTH_4 2 #define MMC_BUS_WIDTH_8 3 - unsigned char timing; /* timing specification used */ - -#define MMC_TIMING_LEGACY 0 -#define MMC_TIMING_MMC_HS 1 -#define MMC_TIMING_SD_HS 2 -#define MMC_TIMING_UHS_SDR12 MMC_TIMING_LEGACY -#define MMC_TIMING_UHS_SDR25 MMC_TIMING_SD_HS -#define MMC_TIMING_UHS_SDR50 3 -#define MMC_TIMING_UHS_SDR104 4 -#define MMC_TIMING_UHS_DDR50 5 -#define MMC_TIMING_MMC_HS200 6 + enum mci_timing timing; /* timing specification used */ #define MMC_SDR_MODE 0 #define MMC_1_2V_DDR_MODE 1 @@ -408,6 +410,7 @@ struct mci_host { unsigned f_max; /**< host interface upper limit */ unsigned clock; /**< Current clock used to talk to the card */ unsigned bus_width; /**< used data bus width to the card */ + enum mci_timing timing; /**< used timing specification to the card */ unsigned max_req_size; unsigned dsr_val; /**< optional dsr value */ int use_dsr; /**< optional dsr usage flag */ |