aboutsummaryrefslogtreecommitdiff
path: root/drivers/mmc/sdhci.c
diff options
context:
space:
mode:
authorWenyou Yang <wenyou.yang@atmel.com>2017-04-26 09:32:30 +0800
committerJaehoon Chung <jh80.chung@samsung.com>2017-05-15 18:28:22 +0900
commit0e0dcc1916fb174966a3f170b69192e0c83ebced (patch)
tree887c79cae29ea018dadb7373b872cb3a037baab0 /drivers/mmc/sdhci.c
parentb5511d6cb8dc601efc14b8cf607553e3ad4fb5e6 (diff)
downloadu-boot-0e0dcc1916fb174966a3f170b69192e0c83ebced.zip
u-boot-0e0dcc1916fb174966a3f170b69192e0c83ebced.tar.gz
u-boot-0e0dcc1916fb174966a3f170b69192e0c83ebced.tar.bz2
mmc: sdhci: Fix maximum clock for programmable clock mode
In the programmable clock mode, the SDCLK frequency is incorrectly assigned when the maximum clock has been assigned during probe, this causes the SDHCI not work well. In the programmable clock mode, when calculating the SDCLK Frequency Select, when the maximum clock has been assigned, it is the actual value, should not be multiplied by host->clk_mul. Otherwise, the maximum clock is multiplied host->clk_mul by the base clock achieved from the BASECLKF field of the Capabilities 0 Register. Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
Diffstat (limited to 'drivers/mmc/sdhci.c')
-rw-r--r--drivers/mmc/sdhci.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index b745977..161a6b1 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -332,8 +332,7 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
*/
if (host->clk_mul) {
for (div = 1; div <= 1024; div++) {
- if ((host->max_clk * host->clk_mul / div)
- <= clock)
+ if ((host->max_clk / div) <= clock)
break;
}
@@ -547,6 +546,14 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
#ifndef CONFIG_DM_MMC_OPS
cfg->ops = &sdhci_ops;
#endif
+
+ /* Check whether the clock multiplier is supported or not */
+ if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
+ caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
+ host->clk_mul = (caps_1 & SDHCI_CLOCK_MUL_MASK) >>
+ SDHCI_CLOCK_MUL_SHIFT;
+ }
+
if (host->max_clk == 0) {
if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
host->max_clk = (caps & SDHCI_CLOCK_V3_BASE_MASK) >>
@@ -555,6 +562,8 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
host->max_clk = (caps & SDHCI_CLOCK_BASE_MASK) >>
SDHCI_CLOCK_BASE_SHIFT;
host->max_clk *= 1000000;
+ if (host->clk_mul)
+ host->max_clk *= host->clk_mul;
}
if (host->max_clk == 0) {
printf("%s: Hardware doesn't specify base clock frequency\n",
@@ -590,11 +599,6 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
if (!(caps & SDHCI_CAN_DO_8BIT))
cfg->host_caps &= ~MMC_MODE_8BIT;
-
- /* Find out whether clock multiplier is supported */
- caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
- host->clk_mul = (caps_1 & SDHCI_CLOCK_MUL_MASK) >>
- SDHCI_CLOCK_MUL_SHIFT;
}
if (host->host_caps)