summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFaiz Abbas <faiz_abbas@ti.com>2021-02-04 15:10:54 +0530
committerLokesh Vutla <lokeshvutla@ti.com>2021-02-04 20:37:57 +0530
commit27a87c834fde4442088fb55322162df9d96db228 (patch)
tree9cc26145f30c7fc6bd6e58cb80bea1f3dceb2e62
parenta759abf569d4f2a238712485379d23f7a5261992 (diff)
downloadu-boot-27a87c834fde4442088fb55322162df9d96db228.tar.gz
u-boot-27a87c834fde4442088fb55322162df9d96db228.tar.bz2
u-boot-27a87c834fde4442088fb55322162df9d96db228.zip
mmc: am654_sdhci: Fix HISPD bit configuration in some lower speed modes
According to the AM654x Data Manual[1], the setup timing in lower speed modes can only be met if the controller uses a falling edge data launch. To ensure this, the HIGH_SPEED_ENA (HOST_CONTROL[2]) bit should be cleared in default speed, SD high speed, MMC high speed, SDR12 and SDR25 speed modes. Use the sdhci writeb callback to implement this condition. [1] http://www.ti.com/lit/gpn/am6546 Section 5.10.5.16.1 Signed-off-by: Faiz Abbas <faiz_abbas@ti.com> Signed-off-by: Aswath Govindraju <a-govindraju@ti.com> Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>
-rw-r--r--drivers/mmc/Kconfig1
-rw-r--r--drivers/mmc/am654_sdhci.c25
2 files changed, 24 insertions, 2 deletions
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 14d7913986..f8ea92172e 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -526,6 +526,7 @@ config MMC_SDHCI_AM654
depends on MMC_SDHCI
depends on DM_MMC && OF_CONTROL && BLK
depends on REGMAP
+ select MMC_SDHCI_IO_ACCESSORS
help
Support for Secure Digital Host Controller Interface (SDHCI)
controllers present on TI's AM654 SOCs.
diff --git a/drivers/mmc/am654_sdhci.c b/drivers/mmc/am654_sdhci.c
index 9549420c65..5dea3eb1be 100644
--- a/drivers/mmc/am654_sdhci.c
+++ b/drivers/mmc/am654_sdhci.c
@@ -369,6 +369,26 @@ static int am654_sdhci_deferred_probe(struct sdhci_host *host)
return sdhci_probe(dev);
}
+static void am654_sdhci_write_b(struct sdhci_host *host, u8 val, int reg)
+{
+ if (reg == SDHCI_HOST_CONTROL) {
+ switch (host->mmc->selected_mode) {
+ /*
+ * According to the data manual, HISPD bit
+ * should not be set in these speed modes.
+ */
+ case SD_HS:
+ case MMC_HS:
+ case UHS_SDR12:
+ case UHS_SDR25:
+ val &= ~SDHCI_CTRL_HISPD;
+ default:
+ break;
+ }
+ }
+
+ writeb(val, host->ioaddr + reg);
+}
#ifdef MMC_SUPPORTS_TUNING
#define ITAP_MAX 32
static int am654_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
@@ -414,6 +434,7 @@ const struct sdhci_ops am654_sdhci_ops = {
.deferred_probe = am654_sdhci_deferred_probe,
.set_ios_post = &am654_sdhci_set_ios_post,
.set_control_reg = &am654_sdhci_set_control_reg,
+ .write_b = am654_sdhci_write_b,
};
const struct am654_driver_data am654_drv_data = {
@@ -455,6 +476,7 @@ const struct sdhci_ops j721e_4bit_sdhci_ops = {
#endif
.deferred_probe = am654_sdhci_deferred_probe,
.set_ios_post = &j721e_4bit_sdhci_set_ios_post,
+ .write_b = am654_sdhci_write_b,
};
const struct am654_driver_data j721e_4bit_drv_data = {
@@ -532,6 +554,7 @@ static int am654_sdhci_probe(struct udevice *dev)
host->max_clk = clock;
host->mmc = &plat->mmc;
host->mmc->dev = dev;
+ host->ops = drv_data->ops;
ret = sdhci_setup_cfg(cfg, host, cfg->f_max,
AM654_SDHCI_MIN_FREQ);
if (ret)
@@ -541,8 +564,6 @@ static int am654_sdhci_probe(struct udevice *dev)
if (ret)
return ret;
- host->ops = drv_data->ops;
-
/* Update ops based on SoC revision */
soc = soc_device_match(am654_sdhci_soc_attr);
if (soc && soc->data) {