aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap/usb.c')
-rw-r--r--arch/arm/plat-omap/usb.c199
1 files changed, 159 insertions, 40 deletions
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c
index 7e8096809be2..25489aafb113 100644
--- a/arch/arm/plat-omap/usb.c
+++ b/arch/arm/plat-omap/usb.c
@@ -37,9 +37,27 @@
37#include <asm/arch/usb.h> 37#include <asm/arch/usb.h>
38#include <asm/arch/board.h> 38#include <asm/arch/board.h>
39 39
40#ifdef CONFIG_ARCH_OMAP1
41
42#define INT_USB_IRQ_GEN IH2_BASE + 20
43#define INT_USB_IRQ_NISO IH2_BASE + 30
44#define INT_USB_IRQ_ISO IH2_BASE + 29
45#define INT_USB_IRQ_HGEN INT_USB_HHC_1
46#define INT_USB_IRQ_OTG IH2_BASE + 8
47
48#else
49
50#define INT_USB_IRQ_GEN INT_24XX_USB_IRQ_GEN
51#define INT_USB_IRQ_NISO INT_24XX_USB_IRQ_NISO
52#define INT_USB_IRQ_ISO INT_24XX_USB_IRQ_ISO
53#define INT_USB_IRQ_HGEN INT_24XX_USB_IRQ_HGEN
54#define INT_USB_IRQ_OTG INT_24XX_USB_IRQ_OTG
55
56#endif
57
58
40/* These routines should handle the standard chip-specific modes 59/* These routines should handle the standard chip-specific modes
41 * for usb0/1/2 ports, covering basic mux and transceiver setup. 60 * for usb0/1/2 ports, covering basic mux and transceiver setup.
42 * Call omap_usb_init() once, from INIT_MACHINE().
43 * 61 *
44 * Some board-*.c files will need to set up additional mux options, 62 * Some board-*.c files will need to set up additional mux options,
45 * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup. 63 * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup.
@@ -96,19 +114,26 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
96{ 114{
97 u32 syscon1 = 0; 115 u32 syscon1 = 0;
98 116
117 if (cpu_is_omap24xx())
118 CONTROL_DEVCONF_REG &= ~USBT0WRMODEI(USB_BIDIR_TLL);
119
99 if (nwires == 0) { 120 if (nwires == 0) {
100 if (!cpu_is_omap15xx()) { 121 if (cpu_class_is_omap1() && !cpu_is_omap15xx()) {
101 /* pulldown D+/D- */ 122 /* pulldown D+/D- */
102 USB_TRANSCEIVER_CTRL_REG &= ~(3 << 1); 123 USB_TRANSCEIVER_CTRL_REG &= ~(3 << 1);
103 } 124 }
104 return 0; 125 return 0;
105 } 126 }
106 127
107 if (is_device) 128 if (is_device) {
108 omap_cfg_reg(W4_USB_PUEN); 129 if (cpu_is_omap24xx())
130 omap_cfg_reg(J20_24XX_USB0_PUEN);
131 else
132 omap_cfg_reg(W4_USB_PUEN);
133 }
109 134
110 /* internal transceiver */ 135 /* internal transceiver (unavailable on 17xx, 24xx) */
111 if (nwires == 2) { 136 if (!cpu_class_is_omap2() && nwires == 2) {
112 // omap_cfg_reg(P9_USB_DP); 137 // omap_cfg_reg(P9_USB_DP);
113 // omap_cfg_reg(R8_USB_DM); 138 // omap_cfg_reg(R8_USB_DM);
114 139
@@ -136,29 +161,50 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
136 return 0; 161 return 0;
137 } 162 }
138 163
139 omap_cfg_reg(V6_USB0_TXD); 164 if (cpu_is_omap24xx()) {
140 omap_cfg_reg(W9_USB0_TXEN); 165 omap_cfg_reg(K18_24XX_USB0_DAT);
141 omap_cfg_reg(W5_USB0_SE0); 166 omap_cfg_reg(K19_24XX_USB0_TXEN);
167 omap_cfg_reg(J14_24XX_USB0_SE0);
168 if (nwires != 3)
169 omap_cfg_reg(J18_24XX_USB0_RCV);
170 } else {
171 omap_cfg_reg(V6_USB0_TXD);
172 omap_cfg_reg(W9_USB0_TXEN);
173 omap_cfg_reg(W5_USB0_SE0);
174 if (nwires != 3)
175 omap_cfg_reg(Y5_USB0_RCV);
176 }
142 177
143 /* NOTE: SPEED and SUSP aren't configured here */ 178 /* NOTE: SPEED and SUSP aren't configured here. OTG hosts
179 * may be able to use I2C requests to set those bits along
180 * with VBUS switching and overcurrent detction.
181 */
144 182
145 if (nwires != 3) 183 if (cpu_class_is_omap1() && nwires != 6)
146 omap_cfg_reg(Y5_USB0_RCV);
147 if (nwires != 6)
148 USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R; 184 USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R;
149 185
150 switch (nwires) { 186 switch (nwires) {
151 case 3: 187 case 3:
152 syscon1 = 2; 188 syscon1 = 2;
189 if (cpu_is_omap24xx())
190 CONTROL_DEVCONF_REG |= USBT0WRMODEI(USB_BIDIR);
153 break; 191 break;
154 case 4: 192 case 4:
155 syscon1 = 1; 193 syscon1 = 1;
194 if (cpu_is_omap24xx())
195 CONTROL_DEVCONF_REG |= USBT0WRMODEI(USB_BIDIR);
156 break; 196 break;
157 case 6: 197 case 6:
158 syscon1 = 3; 198 syscon1 = 3;
159 omap_cfg_reg(AA9_USB0_VP); 199 if (cpu_is_omap24xx()) {
160 omap_cfg_reg(R9_USB0_VM); 200 omap_cfg_reg(J19_24XX_USB0_VP);
161 USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R; 201 omap_cfg_reg(K20_24XX_USB0_VM);
202 CONTROL_DEVCONF_REG |= USBT0WRMODEI(USB_UNIDIR);
203 } else {
204 omap_cfg_reg(AA9_USB0_VP);
205 omap_cfg_reg(R9_USB0_VM);
206 USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R;
207 }
162 break; 208 break;
163 default: 209 default:
164 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", 210 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
@@ -171,14 +217,22 @@ static u32 __init omap_usb1_init(unsigned nwires)
171{ 217{
172 u32 syscon1 = 0; 218 u32 syscon1 = 0;
173 219
174 if (nwires != 6 && !cpu_is_omap15xx()) 220 if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6)
175 USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB1_UNI_R; 221 USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB1_UNI_R;
222 if (cpu_is_omap24xx())
223 CONTROL_DEVCONF_REG &= ~USBT1WRMODEI(USB_BIDIR_TLL);
224
176 if (nwires == 0) 225 if (nwires == 0)
177 return 0; 226 return 0;
178 227
179 /* external transceiver */ 228 /* external transceiver */
180 omap_cfg_reg(USB1_TXD); 229 if (cpu_class_is_omap1()) {
181 omap_cfg_reg(USB1_TXEN); 230 omap_cfg_reg(USB1_TXD);
231 omap_cfg_reg(USB1_TXEN);
232 if (nwires != 3)
233 omap_cfg_reg(USB1_RCV);
234 }
235
182 if (cpu_is_omap15xx()) { 236 if (cpu_is_omap15xx()) {
183 omap_cfg_reg(USB1_SEO); 237 omap_cfg_reg(USB1_SEO);
184 omap_cfg_reg(USB1_SPEED); 238 omap_cfg_reg(USB1_SPEED);
@@ -190,20 +244,38 @@ static u32 __init omap_usb1_init(unsigned nwires)
190 } else if (cpu_is_omap1710()) { 244 } else if (cpu_is_omap1710()) {
191 omap_cfg_reg(R13_1710_USB1_SE0); 245 omap_cfg_reg(R13_1710_USB1_SE0);
192 // SUSP 246 // SUSP
247 } else if (cpu_is_omap24xx()) {
248 /* NOTE: board-specific code must set up pin muxing for usb1,
249 * since each signal could come out on either of two balls.
250 */
193 } else { 251 } else {
194 pr_debug("usb unrecognized\n"); 252 pr_debug("usb%d cpu unrecognized\n", 1);
253 return 0;
195 } 254 }
196 if (nwires != 3)
197 omap_cfg_reg(USB1_RCV);
198 255
199 switch (nwires) { 256 switch (nwires) {
257 case 2:
258 if (!cpu_is_omap24xx())
259 goto bad;
260 /* NOTE: board-specific code must override this setting if
261 * this TLL link is not using DP/DM
262 */
263 syscon1 = 1;
264 CONTROL_DEVCONF_REG |= USBT1WRMODEI(USB_BIDIR_TLL);
265 break;
200 case 3: 266 case 3:
201 syscon1 = 2; 267 syscon1 = 2;
268 if (cpu_is_omap24xx())
269 CONTROL_DEVCONF_REG |= USBT1WRMODEI(USB_BIDIR);
202 break; 270 break;
203 case 4: 271 case 4:
204 syscon1 = 1; 272 syscon1 = 1;
273 if (cpu_is_omap24xx())
274 CONTROL_DEVCONF_REG |= USBT1WRMODEI(USB_BIDIR);
205 break; 275 break;
206 case 6: 276 case 6:
277 if (cpu_is_omap24xx())
278 goto bad;
207 syscon1 = 3; 279 syscon1 = 3;
208 omap_cfg_reg(USB1_VP); 280 omap_cfg_reg(USB1_VP);
209 omap_cfg_reg(USB1_VM); 281 omap_cfg_reg(USB1_VM);
@@ -211,6 +283,7 @@ static u32 __init omap_usb1_init(unsigned nwires)
211 USB_TRANSCEIVER_CTRL_REG |= CONF_USB1_UNI_R; 283 USB_TRANSCEIVER_CTRL_REG |= CONF_USB1_UNI_R;
212 break; 284 break;
213 default: 285 default:
286bad:
214 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", 287 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
215 1, nwires); 288 1, nwires);
216 } 289 }
@@ -221,10 +294,17 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
221{ 294{
222 u32 syscon1 = 0; 295 u32 syscon1 = 0;
223 296
224 /* NOTE erratum: must leave USB2_UNI_R set if usb0 in use */ 297 if (cpu_is_omap24xx()) {
298 CONTROL_DEVCONF_REG &= ~(USBT2WRMODEI(USB_BIDIR_TLL)
299 | USBT2TLL5PI);
300 alt_pingroup = 0;
301 }
302
303 /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */
225 if (alt_pingroup || nwires == 0) 304 if (alt_pingroup || nwires == 0)
226 return 0; 305 return 0;
227 if (nwires != 6 && !cpu_is_omap15xx()) 306
307 if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6)
228 USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R; 308 USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R;
229 309
230 /* external transceiver */ 310 /* external transceiver */
@@ -242,19 +322,54 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
242 if (nwires != 3) 322 if (nwires != 3)
243 omap_cfg_reg(Y5_USB2_RCV); 323 omap_cfg_reg(Y5_USB2_RCV);
244 // FIXME omap_cfg_reg(USB2_SPEED); 324 // FIXME omap_cfg_reg(USB2_SPEED);
325 } else if (cpu_is_omap24xx()) {
326 omap_cfg_reg(Y11_24XX_USB2_DAT);
327 omap_cfg_reg(AA10_24XX_USB2_SE0);
328 if (nwires > 2)
329 omap_cfg_reg(AA12_24XX_USB2_TXEN);
330 if (nwires > 3)
331 omap_cfg_reg(AA6_24XX_USB2_RCV);
245 } else { 332 } else {
246 pr_debug("usb unrecognized\n"); 333 pr_debug("usb%d cpu unrecognized\n", 1);
334 return 0;
247 } 335 }
248 // omap_cfg_reg(USB2_SUSP); 336 // if (cpu_class_is_omap1()) omap_cfg_reg(USB2_SUSP);
249 337
250 switch (nwires) { 338 switch (nwires) {
339 case 2:
340 if (!cpu_is_omap24xx())
341 goto bad;
342 /* NOTE: board-specific code must override this setting if
343 * this TLL link is not using DP/DM
344 */
345 syscon1 = 1;
346 CONTROL_DEVCONF_REG |= USBT2WRMODEI(USB_BIDIR_TLL);
347 break;
251 case 3: 348 case 3:
252 syscon1 = 2; 349 syscon1 = 2;
350 if (cpu_is_omap24xx())
351 CONTROL_DEVCONF_REG |= USBT2WRMODEI(USB_BIDIR);
253 break; 352 break;
254 case 4: 353 case 4:
255 syscon1 = 1; 354 syscon1 = 1;
355 if (cpu_is_omap24xx())
356 CONTROL_DEVCONF_REG |= USBT2WRMODEI(USB_BIDIR);
357 break;
358 case 5:
359 if (!cpu_is_omap24xx())
360 goto bad;
361 omap_cfg_reg(AA4_24XX_USB2_TLLSE0);
362 /* NOTE: board-specific code must override this setting if
363 * this TLL link is not using DP/DM. Something must also
364 * set up OTG_SYSCON2.HMC_TLL{ATTACH,SPEED}
365 */
366 syscon1 = 3;
367 CONTROL_DEVCONF_REG |= USBT2WRMODEI(USB_UNIDIR_TLL)
368 | USBT2TLL5PI;
256 break; 369 break;
257 case 6: 370 case 6:
371 if (cpu_is_omap24xx())
372 goto bad;
258 syscon1 = 3; 373 syscon1 = 3;
259 if (cpu_is_omap15xx()) { 374 if (cpu_is_omap15xx()) {
260 omap_cfg_reg(USB2_VP); 375 omap_cfg_reg(USB2_VP);
@@ -266,6 +381,7 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
266 } 381 }
267 break; 382 break;
268 default: 383 default:
384bad:
269 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", 385 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
270 2, nwires); 386 2, nwires);
271 } 387 }
@@ -294,13 +410,13 @@ static struct resource udc_resources[] = {
294 .end = UDC_BASE + 0xff, 410 .end = UDC_BASE + 0xff,
295 .flags = IORESOURCE_MEM, 411 .flags = IORESOURCE_MEM,
296 }, { /* general IRQ */ 412 }, { /* general IRQ */
297 .start = IH2_BASE + 20, 413 .start = INT_USB_IRQ_GEN,
298 .flags = IORESOURCE_IRQ, 414 .flags = IORESOURCE_IRQ,
299 }, { /* PIO IRQ */ 415 }, { /* PIO IRQ */
300 .start = IH2_BASE + 30, 416 .start = INT_USB_IRQ_NISO,
301 .flags = IORESOURCE_IRQ, 417 .flags = IORESOURCE_IRQ,
302 }, { /* SOF IRQ */ 418 }, { /* SOF IRQ */
303 .start = IH2_BASE + 29, 419 .start = INT_USB_IRQ_ISO,
304 .flags = IORESOURCE_IRQ, 420 .flags = IORESOURCE_IRQ,
305 }, 421 },
306}; 422};
@@ -329,11 +445,11 @@ static u64 ohci_dmamask = ~(u32)0;
329static struct resource ohci_resources[] = { 445static struct resource ohci_resources[] = {
330 { 446 {
331 .start = OMAP_OHCI_BASE, 447 .start = OMAP_OHCI_BASE,
332 .end = OMAP_OHCI_BASE + 4096 - 1, 448 .end = OMAP_OHCI_BASE + 0xff,
333 .flags = IORESOURCE_MEM, 449 .flags = IORESOURCE_MEM,
334 }, 450 },
335 { 451 {
336 .start = INT_USB_HHC_1, 452 .start = INT_USB_IRQ_HGEN,
337 .flags = IORESOURCE_IRQ, 453 .flags = IORESOURCE_IRQ,
338 }, 454 },
339}; 455};
@@ -361,7 +477,7 @@ static struct resource otg_resources[] = {
361 .end = OTG_BASE + 0xff, 477 .end = OTG_BASE + 0xff,
362 .flags = IORESOURCE_MEM, 478 .flags = IORESOURCE_MEM,
363 }, { 479 }, {
364 .start = IH2_BASE + 8, 480 .start = INT_USB_IRQ_OTG,
365 .flags = IORESOURCE_IRQ, 481 .flags = IORESOURCE_IRQ,
366 }, 482 },
367}; 483};
@@ -385,7 +501,7 @@ static struct platform_device otg_device = {
385 501
386 502
387// FIXME correct answer depends on hmc_mode, 503// FIXME correct answer depends on hmc_mode,
388// as does any nonzero value for config->otg port number 504// as does (on omap1) any nonzero value for config->otg port number
389#ifdef CONFIG_USB_GADGET_OMAP 505#ifdef CONFIG_USB_GADGET_OMAP
390#define is_usb0_device(config) 1 506#define is_usb0_device(config) 1
391#else 507#else
@@ -426,12 +542,13 @@ omap_otg_init(struct omap_usb_config *config)
426 if (config->otg) 542 if (config->otg)
427 syscon |= OTG_EN; 543 syscon |= OTG_EN;
428#endif 544#endif
429 pr_debug("USB_TRANSCEIVER_CTRL_REG = %03x\n", USB_TRANSCEIVER_CTRL_REG); 545 if (cpu_class_is_omap1())
546 pr_debug("USB_TRANSCEIVER_CTRL_REG = %03x\n", USB_TRANSCEIVER_CTRL_REG);
430 pr_debug("OTG_SYSCON_2_REG = %08x\n", syscon); 547 pr_debug("OTG_SYSCON_2_REG = %08x\n", syscon);
431 OTG_SYSCON_2_REG = syscon; 548 OTG_SYSCON_2_REG = syscon;
432 549
433 printk("USB: hmc %d", config->hmc_mode); 550 printk("USB: hmc %d", config->hmc_mode);
434 if (alt_pingroup) 551 if (!alt_pingroup)
435 printk(", usb2 alt %d wires", config->pins[2]); 552 printk(", usb2 alt %d wires", config->pins[2]);
436 else if (config->pins[0]) 553 else if (config->pins[0])
437 printk(", usb0 %d wires%s", config->pins[0], 554 printk(", usb0 %d wires%s", config->pins[0],
@@ -444,10 +561,12 @@ omap_otg_init(struct omap_usb_config *config)
444 printk(", Mini-AB on usb%d", config->otg - 1); 561 printk(", Mini-AB on usb%d", config->otg - 1);
445 printk("\n"); 562 printk("\n");
446 563
447 /* leave USB clocks/controllers off until needed */ 564 if (cpu_class_is_omap1()) {
448 ULPD_SOFT_REQ_REG &= ~SOFT_USB_CLK_REQ; 565 /* leave USB clocks/controllers off until needed */
449 ULPD_CLOCK_CTRL_REG &= ~USB_MCLK_EN; 566 ULPD_SOFT_REQ_REG &= ~SOFT_USB_CLK_REQ;
450 ULPD_CLOCK_CTRL_REG |= DIS_USB_PVCI_CLK; 567 ULPD_CLOCK_CTRL_REG &= ~USB_MCLK_EN;
568 ULPD_CLOCK_CTRL_REG |= DIS_USB_PVCI_CLK;
569 }
451 syscon = OTG_SYSCON_1_REG; 570 syscon = OTG_SYSCON_1_REG;
452 syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN; 571 syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN;
453 572
@@ -585,7 +704,7 @@ omap_usb_init(void)
585 } 704 }
586 platform_data = *config; 705 platform_data = *config;
587 706
588 if (cpu_is_omap730() || cpu_is_omap16xx()) 707 if (cpu_is_omap730() || cpu_is_omap16xx() || cpu_is_omap24xx())
589 omap_otg_init(&platform_data); 708 omap_otg_init(&platform_data);
590 else if (cpu_is_omap15xx()) 709 else if (cpu_is_omap15xx())
591 omap_1510_usb_init(&platform_data); 710 omap_1510_usb_init(&platform_data);