diff options
Diffstat (limited to 'drivers/mmc/host/mmci.c')
-rw-r--r-- | drivers/mmc/host/mmci.c | 21 |
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 | */ |
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; |