diff options
author | Zhangfei Gao <zgao6@marvell.com> | 2010-08-05 19:10:01 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2010-10-23 09:11:14 -0400 |
commit | 85105c53b0ce70a277160379f9d89309cefc0bfd (patch) | |
tree | adb882eec66c71605752e75c8bba224be2fefd69 /drivers/mmc/host | |
parent | 0957c3339efa333b7895157eb18b9b578394f80c (diff) |
mmc: SDHC 3.0: support 10-bit divided clock mode
Signed-off-by: Zhangfei Gao <zgao6@marvell.com>
Cc: Michał Mirosław <mirqus@gmail.com>
Cc: David Vrabel <david.vrabel@csr.com>
Reviewed-by: Matt Fleming <matt@console-pimps.org>
Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r-- | drivers/mmc/host/sdhci.c | 25 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 5 |
2 files changed, 25 insertions, 5 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index e0536175185a..4432fec7467a 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -1001,13 +1001,28 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) | |||
1001 | if (clock == 0) | 1001 | if (clock == 0) |
1002 | goto out; | 1002 | goto out; |
1003 | 1003 | ||
1004 | for (div = 1;div < 256;div *= 2) { | 1004 | if (host->version >= SDHCI_SPEC_300) { |
1005 | if ((host->max_clk / div) <= clock) | 1005 | /* Version 3.00 divisors must be a multiple of 2. */ |
1006 | break; | 1006 | if (host->max_clk <= clock) |
1007 | div = 1; | ||
1008 | else { | ||
1009 | for (div = 2; div < 2046; div += 2) { | ||
1010 | if ((host->max_clk / div) <= clock) | ||
1011 | break; | ||
1012 | } | ||
1013 | } | ||
1014 | } else { | ||
1015 | /* Version 2.00 divisors must be a power of 2. */ | ||
1016 | for (div = 1; div < 256; div *= 2) { | ||
1017 | if ((host->max_clk / div) <= clock) | ||
1018 | break; | ||
1019 | } | ||
1007 | } | 1020 | } |
1008 | div >>= 1; | 1021 | div >>= 1; |
1009 | 1022 | ||
1010 | clk = div << SDHCI_DIVIDER_SHIFT; | 1023 | clk = (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; |
1024 | clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) | ||
1025 | << SDHCI_DIVIDER_HI_SHIFT; | ||
1011 | clk |= SDHCI_CLOCK_INT_EN; | 1026 | clk |= SDHCI_CLOCK_INT_EN; |
1012 | sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); | 1027 | sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); |
1013 | 1028 | ||
@@ -1708,7 +1723,7 @@ int sdhci_add_host(struct sdhci_host *host) | |||
1708 | host->version = sdhci_readw(host, SDHCI_HOST_VERSION); | 1723 | host->version = sdhci_readw(host, SDHCI_HOST_VERSION); |
1709 | host->version = (host->version & SDHCI_SPEC_VER_MASK) | 1724 | host->version = (host->version & SDHCI_SPEC_VER_MASK) |
1710 | >> SDHCI_SPEC_VER_SHIFT; | 1725 | >> SDHCI_SPEC_VER_SHIFT; |
1711 | if (host->version > SDHCI_SPEC_200) { | 1726 | if (host->version > SDHCI_SPEC_300) { |
1712 | printk(KERN_ERR "%s: Unknown controller version (%d). " | 1727 | printk(KERN_ERR "%s: Unknown controller version (%d). " |
1713 | "You may experience problems.\n", mmc_hostname(mmc), | 1728 | "You may experience problems.\n", mmc_hostname(mmc), |
1714 | host->version); | 1729 | host->version); |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index d316bc79b636..950d4fd90072 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -86,6 +86,10 @@ | |||
86 | 86 | ||
87 | #define SDHCI_CLOCK_CONTROL 0x2C | 87 | #define SDHCI_CLOCK_CONTROL 0x2C |
88 | #define SDHCI_DIVIDER_SHIFT 8 | 88 | #define SDHCI_DIVIDER_SHIFT 8 |
89 | #define SDHCI_DIVIDER_HI_SHIFT 6 | ||
90 | #define SDHCI_DIV_MASK 0xFF | ||
91 | #define SDHCI_DIV_MASK_LEN 8 | ||
92 | #define SDHCI_DIV_HI_MASK 0x300 | ||
89 | #define SDHCI_CLOCK_CARD_EN 0x0004 | 93 | #define SDHCI_CLOCK_CARD_EN 0x0004 |
90 | #define SDHCI_CLOCK_INT_STABLE 0x0002 | 94 | #define SDHCI_CLOCK_INT_STABLE 0x0002 |
91 | #define SDHCI_CLOCK_INT_EN 0x0001 | 95 | #define SDHCI_CLOCK_INT_EN 0x0001 |
@@ -178,6 +182,7 @@ | |||
178 | #define SDHCI_SPEC_VER_SHIFT 0 | 182 | #define SDHCI_SPEC_VER_SHIFT 0 |
179 | #define SDHCI_SPEC_100 0 | 183 | #define SDHCI_SPEC_100 0 |
180 | #define SDHCI_SPEC_200 1 | 184 | #define SDHCI_SPEC_200 1 |
185 | #define SDHCI_SPEC_300 2 | ||
181 | 186 | ||
182 | struct sdhci_ops; | 187 | struct sdhci_ops; |
183 | 188 | ||