aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/hsmmc.c
diff options
context:
space:
mode:
authorkishore kadiyala <kishore.kadiyala@ti.com>2010-05-15 14:21:25 -0400
committerTony Lindgren <tony@atomide.com>2010-05-20 14:21:22 -0400
commitc83c8e6cde35c51a120952f54b4e4ecda6fa58a5 (patch)
treefa92fc248a25905730352d317bbf67a0c0e20602 /arch/arm/mach-omap2/hsmmc.c
parent717c1fbf7c139c3c5d5920b29bdf196d07a40c8a (diff)
omap4: Adding PBIAS Configuration for MMC1 Controller
In OMAP4, MMC1 PBIAS and its associated IO is software-controlled by CONTROL_PBIAS and CONTROL_MMC1 registers. This patch adds PBIAS configuration for MMC1 Controller during power-ON and power-OFF of regulator. Signed-off-by: Kishore Kadiyala <kishore.kadiyala@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/mach-omap2/hsmmc.c')
-rw-r--r--arch/arm/mach-omap2/hsmmc.c97
1 files changed, 88 insertions, 9 deletions
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 2d36f3afbd4e..1ef54b036103 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -24,6 +24,7 @@
24 24
25static u16 control_pbias_offset; 25static u16 control_pbias_offset;
26static u16 control_devconf1_offset; 26static u16 control_devconf1_offset;
27static u16 control_mmc1;
27 28
28#define HSMMC_NAME_LEN 9 29#define HSMMC_NAME_LEN 9
29 30
@@ -42,7 +43,7 @@ static int hsmmc_get_context_loss(struct device *dev)
42#define hsmmc_get_context_loss NULL 43#define hsmmc_get_context_loss NULL
43#endif 44#endif
44 45
45static void hsmmc1_before_set_reg(struct device *dev, int slot, 46static void omap_hsmmc1_before_set_reg(struct device *dev, int slot,
46 int power_on, int vdd) 47 int power_on, int vdd)
47{ 48{
48 u32 reg, prog_io; 49 u32 reg, prog_io;
@@ -95,7 +96,7 @@ static void hsmmc1_before_set_reg(struct device *dev, int slot,
95 } 96 }
96} 97}
97 98
98static void hsmmc1_after_set_reg(struct device *dev, int slot, 99static void omap_hsmmc1_after_set_reg(struct device *dev, int slot,
99 int power_on, int vdd) 100 int power_on, int vdd)
100{ 101{
101 u32 reg; 102 u32 reg;
@@ -119,6 +120,60 @@ static void hsmmc1_after_set_reg(struct device *dev, int slot,
119 } 120 }
120} 121}
121 122
123static void omap4_hsmmc1_before_set_reg(struct device *dev, int slot,
124 int power_on, int vdd)
125{
126 u32 reg;
127
128 /*
129 * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
130 * card with Vcc regulator (from twl4030 or whatever). OMAP has both
131 * 1.8V and 3.0V modes, controlled by the PBIAS register.
132 *
133 * In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which
134 * is most naturally TWL VSIM; those pins also use PBIAS.
135 *
136 * FIXME handle VMMC1A as needed ...
137 */
138 reg = omap_ctrl_readl(control_pbias_offset);
139 reg &= ~(OMAP4_MMC1_PBIASLITE_PWRDNZ | OMAP4_MMC1_PWRDNZ |
140 OMAP4_USBC1_ICUSB_PWRDNZ);
141 omap_ctrl_writel(reg, control_pbias_offset);
142}
143
144static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot,
145 int power_on, int vdd)
146{
147 u32 reg;
148
149 if (power_on) {
150 reg = omap_ctrl_readl(control_pbias_offset);
151 reg |= OMAP4_MMC1_PBIASLITE_PWRDNZ;
152 if ((1 << vdd) <= MMC_VDD_165_195)
153 reg &= ~OMAP4_MMC1_PBIASLITE_VMODE;
154 else
155 reg |= OMAP4_MMC1_PBIASLITE_VMODE;
156 reg |= (OMAP4_MMC1_PBIASLITE_PWRDNZ | OMAP4_MMC1_PWRDNZ |
157 OMAP4_USBC1_ICUSB_PWRDNZ);
158 omap_ctrl_writel(reg, control_pbias_offset);
159 /* 4 microsec delay for comparator to generate an error*/
160 udelay(4);
161 reg = omap_ctrl_readl(control_pbias_offset);
162 if (reg & OMAP4_MMC1_PBIASLITE_VMODE_ERROR) {
163 pr_err("Pbias Voltage is not same as LDO\n");
164 /* Caution : On VMODE_ERROR Power Down MMC IO */
165 reg &= ~(OMAP4_MMC1_PWRDNZ | OMAP4_USBC1_ICUSB_PWRDNZ);
166 omap_ctrl_writel(reg, control_pbias_offset);
167 }
168 } else {
169 reg = omap_ctrl_readl(control_pbias_offset);
170 reg |= (OMAP4_MMC1_PBIASLITE_PWRDNZ |
171 OMAP4_MMC1_PBIASLITE_VMODE | OMAP4_MMC1_PWRDNZ |
172 OMAP4_USBC1_ICUSB_PWRDNZ);
173 omap_ctrl_writel(reg, control_pbias_offset);
174 }
175}
176
122static void hsmmc23_before_set_reg(struct device *dev, int slot, 177static void hsmmc23_before_set_reg(struct device *dev, int slot,
123 int power_on, int vdd) 178 int power_on, int vdd)
124{ 179{
@@ -152,13 +207,28 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
152 struct omap2_hsmmc_info *c; 207 struct omap2_hsmmc_info *c;
153 int nr_hsmmc = ARRAY_SIZE(hsmmc_data); 208 int nr_hsmmc = ARRAY_SIZE(hsmmc_data);
154 int i; 209 int i;
210 u32 reg;
155 211
156 if (cpu_is_omap2430()) { 212 if (!cpu_is_omap44xx()) {
157 control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE; 213 if (cpu_is_omap2430()) {
158 control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1; 214 control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE;
215 control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1;
216 } else {
217 control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE;
218 control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1;
219 }
159 } else { 220 } else {
160 control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE; 221 control_pbias_offset = OMAP44XX_CONTROL_PBIAS_LITE;
161 control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1; 222 control_mmc1 = OMAP44XX_CONTROL_MMC1;
223 reg = omap_ctrl_readl(control_mmc1);
224 reg |= (OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP0 |
225 OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP1);
226 reg &= ~(OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP2 |
227 OMAP4_CONTROL_SDMMC1_PUSTRENGTHGRP3);
228 reg |= (OMAP4_CONTROL_SDMMC1_DR0_SPEEDCTRL |
229 OMAP4_CONTROL_SDMMC1_DR1_SPEEDCTRL |
230 OMAP4_CONTROL_SDMMC1_DR2_SPEEDCTRL);
231 omap_ctrl_writel(reg, control_mmc1);
162 } 232 }
163 233
164 for (c = controllers; c->mmc; c++) { 234 for (c = controllers; c->mmc; c++) {
@@ -231,8 +301,17 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
231 case 1: 301 case 1:
232 if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { 302 if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
233 /* on-chip level shifting via PBIAS0/PBIAS1 */ 303 /* on-chip level shifting via PBIAS0/PBIAS1 */
234 mmc->slots[0].before_set_reg = hsmmc1_before_set_reg; 304 if (cpu_is_omap44xx()) {
235 mmc->slots[0].after_set_reg = hsmmc1_after_set_reg; 305 mmc->slots[0].before_set_reg =
306 omap4_hsmmc1_before_set_reg;
307 mmc->slots[0].after_set_reg =
308 omap4_hsmmc1_after_set_reg;
309 } else {
310 mmc->slots[0].before_set_reg =
311 omap_hsmmc1_before_set_reg;
312 mmc->slots[0].after_set_reg =
313 omap_hsmmc1_after_set_reg;
314 }
236 } 315 }
237 316
238 /* Omap3630 HSMMC1 supports only 4-bit */ 317 /* Omap3630 HSMMC1 supports only 4-bit */