diff options
author | Ludovic Desroches <ludovic.desroches@atmel.com> | 2012-03-21 11:41:23 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2012-04-05 20:32:22 -0400 |
commit | faf8180b20882b52145b96d6d4ed082d41908f90 (patch) | |
tree | 457276f731216938caa2b82d851c770cf3b7dd1e /drivers/mmc | |
parent | 33ab4bbbdf6c60a8c196b5a28215a93aa2a4ed2e (diff) |
mmc: atmel-mci: add support for odd clock dividers
Add an odd clock divider capability available from v5xx. It also involves
changing the clock divider calculation, and changing the switch-case
statement to use top-down fallthrough.
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/atmel-mci-regs.h | 1 | ||||
-rw-r--r-- | drivers/mmc/host/atmel-mci.c | 48 |
2 files changed, 30 insertions, 19 deletions
diff --git a/drivers/mmc/host/atmel-mci-regs.h b/drivers/mmc/host/atmel-mci-regs.h index 000b3ad0f5ca..787aba1682bb 100644 --- a/drivers/mmc/host/atmel-mci-regs.h +++ b/drivers/mmc/host/atmel-mci-regs.h | |||
@@ -31,6 +31,7 @@ | |||
31 | # define ATMCI_MR_PDCFBYTE ( 1 << 13) /* Force Byte Transfer */ | 31 | # define ATMCI_MR_PDCFBYTE ( 1 << 13) /* Force Byte Transfer */ |
32 | # define ATMCI_MR_PDCPADV ( 1 << 14) /* Padding Value */ | 32 | # define ATMCI_MR_PDCPADV ( 1 << 14) /* Padding Value */ |
33 | # define ATMCI_MR_PDCMODE ( 1 << 15) /* PDC-oriented Mode */ | 33 | # define ATMCI_MR_PDCMODE ( 1 << 15) /* PDC-oriented Mode */ |
34 | # define ATMCI_MR_CLKODD(x) ((x) << 16) /* LSB of Clock Divider */ | ||
34 | #define ATMCI_DTOR 0x0008 /* Data Timeout */ | 35 | #define ATMCI_DTOR 0x0008 /* Data Timeout */ |
35 | # define ATMCI_DTOCYC(x) ((x) << 0) /* Data Timeout Cycles */ | 36 | # define ATMCI_DTOCYC(x) ((x) << 0) /* Data Timeout Cycles */ |
36 | # define ATMCI_DTOMUL(x) ((x) << 4) /* Data Timeout Multiplier */ | 37 | # define ATMCI_DTOMUL(x) ((x) << 4) /* Data Timeout Multiplier */ |
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index c56edc4a8e26..e94476beca18 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c | |||
@@ -77,6 +77,7 @@ struct atmel_mci_caps { | |||
77 | bool has_cstor_reg; | 77 | bool has_cstor_reg; |
78 | bool has_highspeed; | 78 | bool has_highspeed; |
79 | bool has_rwproof; | 79 | bool has_rwproof; |
80 | bool has_odd_clk_div; | ||
80 | }; | 81 | }; |
81 | 82 | ||
82 | struct atmel_mci_dma { | 83 | struct atmel_mci_dma { |
@@ -1134,16 +1135,27 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1134 | } | 1135 | } |
1135 | 1136 | ||
1136 | /* Calculate clock divider */ | 1137 | /* Calculate clock divider */ |
1137 | clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * clock_min) - 1; | 1138 | if (host->caps.has_odd_clk_div) { |
1138 | if (clkdiv > 255) { | 1139 | clkdiv = DIV_ROUND_UP(host->bus_hz, clock_min) - 2; |
1139 | dev_warn(&mmc->class_dev, | 1140 | if (clkdiv > 511) { |
1140 | "clock %u too slow; using %lu\n", | 1141 | dev_warn(&mmc->class_dev, |
1141 | clock_min, host->bus_hz / (2 * 256)); | 1142 | "clock %u too slow; using %lu\n", |
1142 | clkdiv = 255; | 1143 | clock_min, host->bus_hz / (511 + 2)); |
1144 | clkdiv = 511; | ||
1145 | } | ||
1146 | host->mode_reg = ATMCI_MR_CLKDIV(clkdiv >> 1) | ||
1147 | | ATMCI_MR_CLKODD(clkdiv & 1); | ||
1148 | } else { | ||
1149 | clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * clock_min) - 1; | ||
1150 | if (clkdiv > 255) { | ||
1151 | dev_warn(&mmc->class_dev, | ||
1152 | "clock %u too slow; using %lu\n", | ||
1153 | clock_min, host->bus_hz / (2 * 256)); | ||
1154 | clkdiv = 255; | ||
1155 | } | ||
1156 | host->mode_reg = ATMCI_MR_CLKDIV(clkdiv); | ||
1143 | } | 1157 | } |
1144 | 1158 | ||
1145 | host->mode_reg = ATMCI_MR_CLKDIV(clkdiv); | ||
1146 | |||
1147 | /* | 1159 | /* |
1148 | * WRPROOF and RDPROOF prevent overruns/underruns by | 1160 | * WRPROOF and RDPROOF prevent overruns/underruns by |
1149 | * stopping the clock when the FIFO is full/empty. | 1161 | * stopping the clock when the FIFO is full/empty. |
@@ -2014,37 +2026,35 @@ static void __init atmci_get_cap(struct atmel_mci *host) | |||
2014 | "version: 0x%x\n", version); | 2026 | "version: 0x%x\n", version); |
2015 | 2027 | ||
2016 | host->caps.has_dma = 0; | 2028 | host->caps.has_dma = 0; |
2017 | host->caps.has_pdc = 0; | 2029 | host->caps.has_pdc = 1; |
2018 | host->caps.has_cfg_reg = 0; | 2030 | host->caps.has_cfg_reg = 0; |
2019 | host->caps.has_cstor_reg = 0; | 2031 | host->caps.has_cstor_reg = 0; |
2020 | host->caps.has_highspeed = 0; | 2032 | host->caps.has_highspeed = 0; |
2021 | host->caps.has_rwproof = 0; | 2033 | host->caps.has_rwproof = 0; |
2034 | host->caps.has_odd_clk_div = 0; | ||
2022 | 2035 | ||
2023 | /* keep only major version number */ | 2036 | /* keep only major version number */ |
2024 | switch (version & 0xf00) { | 2037 | switch (version & 0xf00) { |
2025 | case 0x100: | ||
2026 | host->caps.has_pdc = 1; | ||
2027 | break; | ||
2028 | case 0x200: | ||
2029 | host->caps.has_pdc = 1; | ||
2030 | host->caps.has_rwproof = 1; | ||
2031 | break; | ||
2032 | case 0x300: | ||
2033 | case 0x400: | ||
2034 | case 0x500: | 2038 | case 0x500: |
2039 | host->caps.has_odd_clk_div = 1; | ||
2040 | case 0x400: | ||
2041 | case 0x300: | ||
2035 | #ifdef CONFIG_AT_HDMAC | 2042 | #ifdef CONFIG_AT_HDMAC |
2036 | host->caps.has_dma = 1; | 2043 | host->caps.has_dma = 1; |
2037 | #else | 2044 | #else |
2038 | host->caps.has_dma = 0; | ||
2039 | dev_info(&host->pdev->dev, | 2045 | dev_info(&host->pdev->dev, |
2040 | "has dma capability but dma engine is not selected, then use pio\n"); | 2046 | "has dma capability but dma engine is not selected, then use pio\n"); |
2041 | #endif | 2047 | #endif |
2048 | host->caps.has_pdc = 0; | ||
2042 | host->caps.has_cfg_reg = 1; | 2049 | host->caps.has_cfg_reg = 1; |
2043 | host->caps.has_cstor_reg = 1; | 2050 | host->caps.has_cstor_reg = 1; |
2044 | host->caps.has_highspeed = 1; | 2051 | host->caps.has_highspeed = 1; |
2052 | case 0x200: | ||
2045 | host->caps.has_rwproof = 1; | 2053 | host->caps.has_rwproof = 1; |
2054 | case 0x100: | ||
2046 | break; | 2055 | break; |
2047 | default: | 2056 | default: |
2057 | host->caps.has_pdc = 0; | ||
2048 | dev_warn(&host->pdev->dev, | 2058 | dev_warn(&host->pdev->dev, |
2049 | "Unmanaged mci version, set minimum capabilities\n"); | 2059 | "Unmanaged mci version, set minimum capabilities\n"); |
2050 | break; | 2060 | break; |