int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
u32 max_clk, u32 min_clk)
{
- u32 caps, caps_1;
+ u32 caps;
+ u32 caps_1 = 0;
caps = sdhci_readl(host, SDHCI_CAPABILITIES);
cfg->host_caps |= MMC_MODE_8BIT;
}
+ if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
+ caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
+
+ if (!(cfg->voltages & MMC_VDD_165_195))
+ caps_1 &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
+ SDHCI_SUPPORT_DDR50);
+
+ if (caps_1 & (SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
+ SDHCI_SUPPORT_DDR50))
+ cfg->host_caps |= MMC_MODE_UHS_SDR12 | MMC_MODE_UHS_SDR25;
+
+ if (caps_1 & SDHCI_SUPPORT_SDR104) {
+ cfg->host_caps |= MMC_MODE_UHS_SDR104 | MMC_MODE_UHS_SDR50;
+ /*
+ * SD3.0: SDR104 is supported so (for eMMC) the caps2
+ * field can be promoted to support HS200.
+ */
+ cfg->host_caps |= MMC_MODE_HS200;
+ } else if (caps_1 & SDHCI_SUPPORT_SDR50) {
+ cfg->host_caps |= MMC_MODE_UHS_SDR50;
+ }
+
+ if (caps_1 & SDHCI_SUPPORT_DDR50)
+ cfg->host_caps |= MMC_MODE_UHS_DDR50;
+
+ if (caps_1 & SDHCI_USE_SDR50_TUNING)
+ cfg->host_caps |= MMC_MODE_NEEDS_TUNING;
+
if (host->host_caps)
cfg->host_caps |= host->host_caps;
-
cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
/*
#define MMC_MODE_8BIT (1 << 3)
#define MMC_MODE_SPI (1 << 4)
#define MMC_MODE_DDR_52MHz (1 << 5)
+#define MMC_MODE_UHS_SDR12 (1 << 6)
+#define MMC_MODE_UHS_SDR25 (1 << 7)
+#define MMC_MODE_UHS_SDR50 (1 << 8)
+#define MMC_MODE_UHS_SDR104 (1 << 9)
+#define MMC_MODE_UHS_DDR50 (1 << 10)
+#define MMC_MODE_NEEDS_TUNING (1 << 11)
+#define MMC_MODE_HS200 (1 << 12)
#define SD_DATA_4BIT 0x00040000
#define SDHCI_CAN_64BIT 0x10000000
#define SDHCI_CAPABILITIES_1 0x44
+#define SDHCI_SUPPORT_SDR50 0x00000001
+#define SDHCI_SUPPORT_SDR104 0x00000002
+#define SDHCI_SUPPORT_DDR50 0x00000004
+#define SDHCI_USE_SDR50_TUNING 0x00002000
+#define SDHCI_SUPPORT_HS400 0x80000000 /* Non-standard */
+
#define SDHCI_CLOCK_MUL_MASK 0x00FF0000
#define SDHCI_CLOCK_MUL_SHIFT 16