aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/mmci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/mmci.c')
-rw-r--r--drivers/mmc/host/mmci.c21
1 files changed, 21 insertions, 0 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 */
58struct variant_data { 59struct 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
70static struct variant_data variant_arm = { 72static 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
93static struct variant_data variant_ux500 = { 96static 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
104static struct variant_data variant_ux500v2 = { 108static 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;