diff options
| -rw-r--r-- | drivers/mmc/host/sdhci-st.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci-st.c b/drivers/mmc/host/sdhci-st.c index 10989edb5100..42a361c14f52 100644 --- a/drivers/mmc/host/sdhci-st.c +++ b/drivers/mmc/host/sdhci-st.c | |||
| @@ -261,6 +261,56 @@ static int sdhci_st_set_dll_for_clock(struct sdhci_host *host) | |||
| 261 | return ret; | 261 | return ret; |
| 262 | } | 262 | } |
| 263 | 263 | ||
| 264 | static void sdhci_st_set_uhs_signaling(struct sdhci_host *host, | ||
| 265 | unsigned int uhs) | ||
| 266 | { | ||
| 267 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
| 268 | struct st_mmc_platform_data *pdata = pltfm_host->priv; | ||
| 269 | u16 ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); | ||
| 270 | int ret = 0; | ||
| 271 | |||
| 272 | /* Select Bus Speed Mode for host */ | ||
| 273 | ctrl_2 &= ~SDHCI_CTRL_UHS_MASK; | ||
| 274 | switch (uhs) { | ||
| 275 | /* | ||
| 276 | * Set V18_EN -- UHS modes do not work without this. | ||
| 277 | * does not change signaling voltage | ||
| 278 | */ | ||
| 279 | |||
| 280 | case MMC_TIMING_UHS_SDR12: | ||
| 281 | st_mmcss_set_static_delay(pdata->top_ioaddr); | ||
| 282 | ctrl_2 |= SDHCI_CTRL_UHS_SDR12 | SDHCI_CTRL_VDD_180; | ||
| 283 | break; | ||
| 284 | case MMC_TIMING_UHS_SDR25: | ||
| 285 | st_mmcss_set_static_delay(pdata->top_ioaddr); | ||
| 286 | ctrl_2 |= SDHCI_CTRL_UHS_SDR25 | SDHCI_CTRL_VDD_180; | ||
| 287 | break; | ||
| 288 | case MMC_TIMING_UHS_SDR50: | ||
| 289 | st_mmcss_set_static_delay(pdata->top_ioaddr); | ||
| 290 | ctrl_2 |= SDHCI_CTRL_UHS_SDR50 | SDHCI_CTRL_VDD_180; | ||
| 291 | ret = sdhci_st_set_dll_for_clock(host); | ||
| 292 | break; | ||
| 293 | case MMC_TIMING_UHS_SDR104: | ||
| 294 | case MMC_TIMING_MMC_HS200: | ||
| 295 | st_mmcss_set_static_delay(pdata->top_ioaddr); | ||
| 296 | ctrl_2 |= SDHCI_CTRL_UHS_SDR104 | SDHCI_CTRL_VDD_180; | ||
| 297 | ret = sdhci_st_set_dll_for_clock(host); | ||
| 298 | break; | ||
| 299 | case MMC_TIMING_UHS_DDR50: | ||
| 300 | case MMC_TIMING_MMC_DDR52: | ||
| 301 | st_mmcss_set_static_delay(pdata->top_ioaddr); | ||
| 302 | ctrl_2 |= SDHCI_CTRL_UHS_DDR50 | SDHCI_CTRL_VDD_180; | ||
| 303 | break; | ||
| 304 | } | ||
| 305 | |||
| 306 | if (ret) | ||
| 307 | dev_warn(mmc_dev(host->mmc), "Error setting dll for clock " | ||
| 308 | "(uhs %d)\n", uhs); | ||
| 309 | |||
| 310 | dev_dbg(mmc_dev(host->mmc), "uhs %d, ctrl_2 %04X\n", uhs, ctrl_2); | ||
| 311 | |||
| 312 | sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); | ||
| 313 | } | ||
| 264 | 314 | ||
| 265 | static u32 sdhci_st_readl(struct sdhci_host *host, int reg) | 315 | static u32 sdhci_st_readl(struct sdhci_host *host, int reg) |
| 266 | { | 316 | { |
| @@ -284,6 +334,7 @@ static const struct sdhci_ops sdhci_st_ops = { | |||
| 284 | .set_bus_width = sdhci_set_bus_width, | 334 | .set_bus_width = sdhci_set_bus_width, |
| 285 | .read_l = sdhci_st_readl, | 335 | .read_l = sdhci_st_readl, |
| 286 | .reset = sdhci_reset, | 336 | .reset = sdhci_reset, |
| 337 | .set_uhs_signaling = sdhci_st_set_uhs_signaling, | ||
| 287 | }; | 338 | }; |
| 288 | 339 | ||
| 289 | static const struct sdhci_pltfm_data sdhci_st_pdata = { | 340 | static const struct sdhci_pltfm_data sdhci_st_pdata = { |
