Message ID | 20210121124052.3454-10-a-govindraju@ti.com |
---|---|
State | Changes Requested |
Delegated to: | Lokesh Vutla |
Headers | show |
Series | Add support for MMC higher speed modes for TI's am65x, j721e and j7200 platforms | expand |
On 1/21/21 9:40 PM, Aswath Govindraju wrote: > From: Faiz Abbas <faiz_abbas@ti.com> > > 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> Best Regards, Jaehoon Chung > --- > drivers/mmc/Kconfig | 1 + > drivers/mmc/am654_sdhci.c | 25 +++++++++++++++++++++++-- > 2 files changed, 24 insertions(+), 2 deletions(-) > > diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig > index 14d79139864a..f8ea92172e44 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 9549420c6582..5dea3eb1be4e 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) { >
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 14d79139864a..f8ea92172e44 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 9549420c6582..5dea3eb1be4e 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) {