diff options
author | Ulf Hansson <ulf.hansson@stericsson.com> | 2011-12-13 10:57:07 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-01-19 19:00:56 -0500 |
commit | 4d1a3a0dc551cfa7304ca46e014231500f3b81a6 (patch) | |
tree | 6ff7bfe536c5335b4821a2100d898861284ae8b2 | |
parent | 7d72a1d48af95211677ea83157945a8ef76b0751 (diff) |
ARM: 7218/1: mmc: mmci: Provide option to configure bus signal direction
The ST Micro variant supports bus signal direction indication. A new
member in the variant struct is added for this.
Moreover the actual signal direction configuration is board specific,
thus the amba mmci platform data is extended with a new member to be
able provide mmci with these specific board configurations.
This patch is based upon a patch from Sebastian Rasmussen.
Tested-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Sebastian Rasmussen <sebastian.rasmussen@stericsson.com>
Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | drivers/mmc/host/mmci.c | 21 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.h | 10 | ||||
-rw-r--r-- | include/linux/amba/mmci.h | 16 |
3 files changed, 37 insertions, 10 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 7cc89beee87f..eb11ce61941d 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -54,6 +54,7 @@ static unsigned int fmax = 515633; | |||
54 | * @st_clkdiv: true if using a ST-specific clock divider algorithm | 54 | * @st_clkdiv: true if using a ST-specific clock divider algorithm |
55 | * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register | 55 | * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register |
56 | * @pwrreg_powerup: power up value for MMCIPOWER register | 56 | * @pwrreg_powerup: power up value for MMCIPOWER register |
57 | * @signal_direction: input/out direction of bus signals can be indicated | ||
57 | */ | 58 | */ |
58 | struct variant_data { | 59 | struct variant_data { |
59 | unsigned int clkreg; | 60 | unsigned int clkreg; |
@@ -65,6 +66,7 @@ struct variant_data { | |||
65 | bool st_clkdiv; | 66 | bool st_clkdiv; |
66 | bool blksz_datactrl16; | 67 | bool blksz_datactrl16; |
67 | u32 pwrreg_powerup; | 68 | u32 pwrreg_powerup; |
69 | bool signal_direction; | ||
68 | }; | 70 | }; |
69 | 71 | ||
70 | static struct variant_data variant_arm = { | 72 | static struct variant_data variant_arm = { |
@@ -88,6 +90,7 @@ static struct variant_data variant_u300 = { | |||
88 | .datalength_bits = 16, | 90 | .datalength_bits = 16, |
89 | .sdio = true, | 91 | .sdio = true, |
90 | .pwrreg_powerup = MCI_PWR_ON, | 92 | .pwrreg_powerup = MCI_PWR_ON, |
93 | .signal_direction = true, | ||
91 | }; | 94 | }; |
92 | 95 | ||
93 | static struct variant_data variant_ux500 = { | 96 | static struct variant_data variant_ux500 = { |
@@ -99,6 +102,7 @@ static struct variant_data variant_ux500 = { | |||
99 | .sdio = true, | 102 | .sdio = true, |
100 | .st_clkdiv = true, | 103 | .st_clkdiv = true, |
101 | .pwrreg_powerup = MCI_PWR_ON, | 104 | .pwrreg_powerup = MCI_PWR_ON, |
105 | .signal_direction = true, | ||
102 | }; | 106 | }; |
103 | 107 | ||
104 | static struct variant_data variant_ux500v2 = { | 108 | static struct variant_data variant_ux500v2 = { |
@@ -111,6 +115,7 @@ static struct variant_data variant_ux500v2 = { | |||
111 | .st_clkdiv = true, | 115 | .st_clkdiv = true, |
112 | .blksz_datactrl16 = true, | 116 | .blksz_datactrl16 = true, |
113 | .pwrreg_powerup = MCI_PWR_ON, | 117 | .pwrreg_powerup = MCI_PWR_ON, |
118 | .signal_direction = true, | ||
114 | }; | 119 | }; |
115 | 120 | ||
116 | /* | 121 | /* |
@@ -1057,6 +1062,22 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1057 | break; | 1062 | break; |
1058 | } | 1063 | } |
1059 | 1064 | ||
1065 | if (variant->signal_direction && ios->power_mode != MMC_POWER_OFF) { | ||
1066 | /* | ||
1067 | * The ST Micro variant has some additional bits | ||
1068 | * indicating signal direction for the signals in | ||
1069 | * the SD/MMC bus and feedback-clock usage. | ||
1070 | */ | ||
1071 | pwr |= host->plat->sigdir; | ||
1072 | |||
1073 | if (ios->bus_width == MMC_BUS_WIDTH_4) | ||
1074 | pwr &= ~MCI_ST_DATA74DIREN; | ||
1075 | else if (ios->bus_width == MMC_BUS_WIDTH_1) | ||
1076 | pwr &= (~MCI_ST_DATA74DIREN & | ||
1077 | ~MCI_ST_DATA31DIREN & | ||
1078 | ~MCI_ST_DATA2DIREN); | ||
1079 | } | ||
1080 | |||
1060 | if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) { | 1081 | if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) { |
1061 | if (host->hw_designer != AMBA_VENDOR_ST) | 1082 | if (host->hw_designer != AMBA_VENDOR_ST) |
1062 | pwr |= MCI_ROD; | 1083 | pwr |= MCI_ROD; |
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 49f153e6ef7a..89eb2e3556d3 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h | |||
@@ -13,16 +13,6 @@ | |||
13 | #define MCI_PWR_ON 0x03 | 13 | #define MCI_PWR_ON 0x03 |
14 | #define MCI_OD (1 << 6) | 14 | #define MCI_OD (1 << 6) |
15 | #define MCI_ROD (1 << 7) | 15 | #define MCI_ROD (1 << 7) |
16 | /* | ||
17 | * The ST Micro version does not have ROD and reuse the voltage registers | ||
18 | * for direction settings | ||
19 | */ | ||
20 | #define MCI_ST_DATA2DIREN (1 << 2) | ||
21 | #define MCI_ST_CMDDIREN (1 << 3) | ||
22 | #define MCI_ST_DATA0DIREN (1 << 4) | ||
23 | #define MCI_ST_DATA31DIREN (1 << 5) | ||
24 | #define MCI_ST_FBCLKEN (1 << 7) | ||
25 | #define MCI_ST_DATA74DIREN (1 << 8) | ||
26 | 16 | ||
27 | #define MMCICLOCK 0x004 | 17 | #define MMCICLOCK 0x004 |
28 | #define MCI_CLK_ENABLE (1 << 8) | 18 | #define MCI_CLK_ENABLE (1 << 8) |
diff --git a/include/linux/amba/mmci.h b/include/linux/amba/mmci.h index 0101e9c17fa1..b51bf5fa85f8 100644 --- a/include/linux/amba/mmci.h +++ b/include/linux/amba/mmci.h | |||
@@ -6,6 +6,19 @@ | |||
6 | 6 | ||
7 | #include <linux/mmc/host.h> | 7 | #include <linux/mmc/host.h> |
8 | 8 | ||
9 | |||
10 | /* | ||
11 | * These defines is places here due to access is needed from machine | ||
12 | * configuration files. The ST Micro version does not have ROD and | ||
13 | * reuse the voltage registers for direction settings. | ||
14 | */ | ||
15 | #define MCI_ST_DATA2DIREN (1 << 2) | ||
16 | #define MCI_ST_CMDDIREN (1 << 3) | ||
17 | #define MCI_ST_DATA0DIREN (1 << 4) | ||
18 | #define MCI_ST_DATA31DIREN (1 << 5) | ||
19 | #define MCI_ST_FBCLKEN (1 << 7) | ||
20 | #define MCI_ST_DATA74DIREN (1 << 8) | ||
21 | |||
9 | /* Just some dummy forwarding */ | 22 | /* Just some dummy forwarding */ |
10 | struct dma_chan; | 23 | struct dma_chan; |
11 | 24 | ||
@@ -31,6 +44,8 @@ struct dma_chan; | |||
31 | * @capabilities: the capabilities of the block as implemented in | 44 | * @capabilities: the capabilities of the block as implemented in |
32 | * this platform, signify anything MMC_CAP_* from mmc/host.h | 45 | * this platform, signify anything MMC_CAP_* from mmc/host.h |
33 | * @capabilities2: more capabilities, MMC_CAP2_* from mmc/host.h | 46 | * @capabilities2: more capabilities, MMC_CAP2_* from mmc/host.h |
47 | * @sigdir: a bit field indicating for what bits in the MMC bus the host | ||
48 | * should enable signal direction indication. | ||
34 | * @dma_filter: function used to select an appropriate RX and TX | 49 | * @dma_filter: function used to select an appropriate RX and TX |
35 | * DMA channel to be used for DMA, if and only if you're deploying the | 50 | * DMA channel to be used for DMA, if and only if you're deploying the |
36 | * generic DMA engine | 51 | * generic DMA engine |
@@ -54,6 +69,7 @@ struct mmci_platform_data { | |||
54 | bool cd_invert; | 69 | bool cd_invert; |
55 | unsigned long capabilities; | 70 | unsigned long capabilities; |
56 | unsigned long capabilities2; | 71 | unsigned long capabilities2; |
72 | u32 sigdir; | ||
57 | bool (*dma_filter)(struct dma_chan *chan, void *filter_param); | 73 | bool (*dma_filter)(struct dma_chan *chan, void *filter_param); |
58 | void *dma_rx_param; | 74 | void *dma_rx_param; |
59 | void *dma_tx_param; | 75 | void *dma_tx_param; |