diff options
| -rw-r--r-- | drivers/mmc/core/mmc.c | 32 | ||||
| -rw-r--r-- | include/linux/mmc/host.h | 2 |
2 files changed, 32 insertions, 2 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index fda54ff43720..39bf4455d16a 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1550,6 +1550,24 @@ out: return ret; } +static int mmc_select_hs_ddr52(struct mmc_host *host) +{ + int err; + + mmc_select_hs(host->card); + mmc_set_clock(host, MMC_HIGH_52_MAX_DTR); + err = mmc_select_bus_width(host->card); + if (err < 0) { + pr_err("%s: %s: select_bus_width failed(%d)\n", + mmc_hostname(host), __func__, err); + return err; + } + + err = mmc_select_hs_ddr(host->card); + + return err; +} + /* * Scale down from HS400 to HS in order to allow frequency change. * This is needed for cards that doesn't support changing frequency in HS400 @@ -1561,10 +1579,20 @@ static int mmc_scale_low(struct mmc_host *host, unsigned long freq) mmc_set_timing(host, MMC_TIMING_LEGACY); mmc_set_clock(host, MMC_HIGH_26_MAX_DTR); + if (host->clk_scaling.lower_bus_speed_mode & + MMC_SCALING_LOWER_DDR52_MODE) { + err = mmc_select_hs_ddr52(host); + if (err) + pr_err("%s: %s: failed to switch to DDR52: err: %d\n", + mmc_hostname(host), __func__, err); + else + return err; + } + err = mmc_select_hs(host->card); if (err) { - pr_err("%s: %s: selecting HS (52Mhz) failed (%d)\n", - mmc_hostname(host), __func__, err); + pr_err("%s: %s: scaling low: failed (%d)\n", + mmc_hostname(host), __func__, err); return err; } diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index e6dd9eb4ead4..38731725cc80 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -335,6 +335,8 @@ struct mmc_devfeq_clk_scaling { unsigned long polling_delay_ms; unsigned int upthreshold; unsigned int downthreshold; + unsigned int lower_bus_speed_mode; +#define MMC_SCALING_LOWER_DDR52_MODE 1 bool need_freq_change; bool clk_scaling_in_progress; bool is_busy_started; |
