1 /* 2 * Platform level USB initialization for FS USB OTG controller on omap1 and 24xx 3 * 4 * Copyright (C) 2004 Texas Instruments, Inc. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 21 #include <linux/module.h> 22 #include <linux/kernel.h> 23 #include <linux/init.h> 24 #include <linux/platform_device.h> 25 #include <linux/io.h> 26 27 #include <asm/irq.h> 28 29 #include <plat/mux.h> 30 #include <plat/usb.h> 31 32 /* These routines should handle the standard chip-specific modes 33 * for usb0/1/2 ports, covering basic mux and transceiver setup. 34 * 35 * Some board-*.c files will need to set up additional mux options, 36 * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup. 37 */ 38 39 /* TESTED ON: 40 * - 1611B H2 (with usb1 mini-AB) using standard Mini-B or OTG cables 41 * - 5912 OSK OHCI (with usb0 standard-A), standard A-to-B cables 42 * - 5912 OSK UDC, with *nonstandard* A-to-A cable 43 * - 1510 Innovator UDC with bundled usb0 cable 44 * - 1510 Innovator OHCI with bundled usb1/usb2 cable 45 * - 1510 Innovator OHCI with custom usb0 cable, feeding 5V VBUS 46 * - 1710 custom development board using alternate pin group 47 * - 1710 H3 (with usb1 mini-AB) using standard Mini-B or OTG cables 48 */ 49 50 #define INT_USB_IRQ_GEN IH2_BASE + 20 51 #define INT_USB_IRQ_NISO IH2_BASE + 30 52 #define INT_USB_IRQ_ISO IH2_BASE + 29 53 #define INT_USB_IRQ_HGEN INT_USB_HHC_1 54 #define INT_USB_IRQ_OTG IH2_BASE + 8 55 56 #ifdef CONFIG_USB_GADGET_OMAP 57 58 static struct resource udc_resources[] = { 59 /* order is significant! */ 60 { /* registers */ 61 .start = UDC_BASE, 62 .end = UDC_BASE + 0xff, 63 .flags = IORESOURCE_MEM, 64 }, { /* general IRQ */ 65 .start = INT_USB_IRQ_GEN, 66 .flags = IORESOURCE_IRQ, 67 }, { /* PIO IRQ */ 68 .start = INT_USB_IRQ_NISO, 69 .flags = IORESOURCE_IRQ, 70 }, { /* SOF IRQ */ 71 .start = INT_USB_IRQ_ISO, 72 .flags = IORESOURCE_IRQ, 73 }, 74 }; 75 76 static u64 udc_dmamask = ~(u32)0; 77 78 static struct platform_device udc_device = { 79 .name = "omap_udc", 80 .id = -1, 81 .dev = { 82 .dma_mask = &udc_dmamask, 83 .coherent_dma_mask = 0xffffffff, 84 }, 85 .num_resources = ARRAY_SIZE(udc_resources), 86 .resource = udc_resources, 87 }; 88 89 static inline void udc_device_init(struct omap_usb_config *pdata) 90 { 91 /* IRQ numbers for omap7xx */ 92 if(cpu_is_omap7xx()) { 93 udc_resources[1].start = INT_7XX_USB_GENI; 94 udc_resources[2].start = INT_7XX_USB_NON_ISO; 95 udc_resources[3].start = INT_7XX_USB_ISO; 96 } 97 pdata->udc_device = &udc_device; 98 } 99 100 #else 101 102 static inline void udc_device_init(struct omap_usb_config *pdata) 103 { 104 } 105 106 #endif 107 108 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) 109 110 /* The dmamask must be set for OHCI to work */ 111 static u64 ohci_dmamask = ~(u32)0; 112 113 static struct resource ohci_resources[] = { 114 { 115 .start = OMAP_OHCI_BASE, 116 .end = OMAP_OHCI_BASE + 0xff, 117 .flags = IORESOURCE_MEM, 118 }, 119 { 120 .start = INT_USB_IRQ_HGEN, 121 .flags = IORESOURCE_IRQ, 122 }, 123 }; 124 125 static struct platform_device ohci_device = { 126 .name = "ohci", 127 .id = -1, 128 .dev = { 129 .dma_mask = &ohci_dmamask, 130 .coherent_dma_mask = 0xffffffff, 131 }, 132 .num_resources = ARRAY_SIZE(ohci_resources), 133 .resource = ohci_resources, 134 }; 135 136 static inline void ohci_device_init(struct omap_usb_config *pdata) 137 { 138 if (cpu_is_omap7xx()) 139 ohci_resources[1].start = INT_7XX_USB_HHC_1; 140 pdata->ohci_device = &ohci_device; 141 } 142 143 #else 144 145 static inline void ohci_device_init(struct omap_usb_config *pdata) 146 { 147 } 148 149 #endif 150 151 #if defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG) 152 153 static struct resource otg_resources[] = { 154 /* order is significant! */ 155 { 156 .start = OTG_BASE, 157 .end = OTG_BASE + 0xff, 158 .flags = IORESOURCE_MEM, 159 }, { 160 .start = INT_USB_IRQ_OTG, 161 .flags = IORESOURCE_IRQ, 162 }, 163 }; 164 165 static struct platform_device otg_device = { 166 .name = "omap_otg", 167 .id = -1, 168 .num_resources = ARRAY_SIZE(otg_resources), 169 .resource = otg_resources, 170 }; 171 172 static inline void otg_device_init(struct omap_usb_config *pdata) 173 { 174 if (cpu_is_omap7xx()) 175 otg_resources[1].start = INT_7XX_USB_OTG; 176 pdata->otg_device = &otg_device; 177 } 178 179 #else 180 181 static inline void otg_device_init(struct omap_usb_config *pdata) 182 { 183 } 184 185 #endif 186 187 u32 __init omap1_usb0_init(unsigned nwires, unsigned is_device) 188 { 189 u32 syscon1 = 0; 190 191 if (nwires == 0) { 192 if (!cpu_is_omap15xx()) { 193 u32 l; 194 195 /* pulldown D+/D- */ 196 l = omap_readl(USB_TRANSCEIVER_CTRL); 197 l &= ~(3 << 1); 198 omap_writel(l, USB_TRANSCEIVER_CTRL); 199 } 200 return 0; 201 } 202 203 if (is_device) { 204 if (cpu_is_omap7xx()) { 205 omap_cfg_reg(AA17_7XX_USB_DM); 206 omap_cfg_reg(W16_7XX_USB_PU_EN); 207 omap_cfg_reg(W17_7XX_USB_VBUSI); 208 omap_cfg_reg(W18_7XX_USB_DMCK_OUT); 209 omap_cfg_reg(W19_7XX_USB_DCRST); 210 } else 211 omap_cfg_reg(W4_USB_PUEN); 212 } 213 214 if (nwires == 2) { 215 u32 l; 216 217 // omap_cfg_reg(P9_USB_DP); 218 // omap_cfg_reg(R8_USB_DM); 219 220 if (cpu_is_omap15xx()) { 221 /* This works on 1510-Innovator */ 222 return 0; 223 } 224 225 /* NOTES: 226 * - peripheral should configure VBUS detection! 227 * - only peripherals may use the internal D+/D- pulldowns 228 * - OTG support on this port not yet written 229 */ 230 231 /* Don't do this for omap7xx -- it causes USB to not work correctly */ 232 if (!cpu_is_omap7xx()) { 233 l = omap_readl(USB_TRANSCEIVER_CTRL); 234 l &= ~(7 << 4); 235 if (!is_device) 236 l |= (3 << 1); 237 omap_writel(l, USB_TRANSCEIVER_CTRL); 238 } 239 240 return 3 << 16; 241 } 242 243 /* alternate pin config, external transceiver */ 244 if (cpu_is_omap15xx()) { 245 printk(KERN_ERR "no usb0 alt pin config on 15xx\n"); 246 return 0; 247 } 248 249 omap_cfg_reg(V6_USB0_TXD); 250 omap_cfg_reg(W9_USB0_TXEN); 251 omap_cfg_reg(W5_USB0_SE0); 252 if (nwires != 3) 253 omap_cfg_reg(Y5_USB0_RCV); 254 255 /* NOTE: SPEED and SUSP aren't configured here. OTG hosts 256 * may be able to use I2C requests to set those bits along 257 * with VBUS switching and overcurrent detection. 258 */ 259 260 if (nwires != 6) { 261 u32 l; 262 263 l = omap_readl(USB_TRANSCEIVER_CTRL); 264 l &= ~CONF_USB2_UNI_R; 265 omap_writel(l, USB_TRANSCEIVER_CTRL); 266 } 267 268 switch (nwires) { 269 case 3: 270 syscon1 = 2; 271 break; 272 case 4: 273 syscon1 = 1; 274 break; 275 case 6: 276 syscon1 = 3; 277 { 278 u32 l; 279 280 omap_cfg_reg(AA9_USB0_VP); 281 omap_cfg_reg(R9_USB0_VM); 282 l = omap_readl(USB_TRANSCEIVER_CTRL); 283 l |= CONF_USB2_UNI_R; 284 omap_writel(l, USB_TRANSCEIVER_CTRL); 285 } 286 break; 287 default: 288 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", 289 0, nwires); 290 } 291 292 return syscon1 << 16; 293 } 294 295 u32 __init omap1_usb1_init(unsigned nwires) 296 { 297 u32 syscon1 = 0; 298 299 if (!cpu_is_omap15xx() && nwires != 6) { 300 u32 l; 301 302 l = omap_readl(USB_TRANSCEIVER_CTRL); 303 l &= ~CONF_USB1_UNI_R; 304 omap_writel(l, USB_TRANSCEIVER_CTRL); 305 } 306 if (nwires == 0) 307 return 0; 308 309 /* external transceiver */ 310 omap_cfg_reg(USB1_TXD); 311 omap_cfg_reg(USB1_TXEN); 312 if (nwires != 3) 313 omap_cfg_reg(USB1_RCV); 314 315 if (cpu_is_omap15xx()) { 316 omap_cfg_reg(USB1_SEO); 317 omap_cfg_reg(USB1_SPEED); 318 // SUSP 319 } else if (cpu_is_omap1610() || cpu_is_omap5912()) { 320 omap_cfg_reg(W13_1610_USB1_SE0); 321 omap_cfg_reg(R13_1610_USB1_SPEED); 322 // SUSP 323 } else if (cpu_is_omap1710()) { 324 omap_cfg_reg(R13_1710_USB1_SE0); 325 // SUSP 326 } else { 327 pr_debug("usb%d cpu unrecognized\n", 1); 328 return 0; 329 } 330 331 switch (nwires) { 332 case 2: 333 goto bad; 334 case 3: 335 syscon1 = 2; 336 break; 337 case 4: 338 syscon1 = 1; 339 break; 340 case 6: 341 syscon1 = 3; 342 omap_cfg_reg(USB1_VP); 343 omap_cfg_reg(USB1_VM); 344 if (!cpu_is_omap15xx()) { 345 u32 l; 346 347 l = omap_readl(USB_TRANSCEIVER_CTRL); 348 l |= CONF_USB1_UNI_R; 349 omap_writel(l, USB_TRANSCEIVER_CTRL); 350 } 351 break; 352 default: 353 bad: 354 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", 355 1, nwires); 356 } 357 358 return syscon1 << 20; 359 } 360 361 u32 __init omap1_usb2_init(unsigned nwires, unsigned alt_pingroup) 362 { 363 u32 syscon1 = 0; 364 365 /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */ 366 if (alt_pingroup || nwires == 0) 367 return 0; 368 369 if (!cpu_is_omap15xx() && nwires != 6) { 370 u32 l; 371 372 l = omap_readl(USB_TRANSCEIVER_CTRL); 373 l &= ~CONF_USB2_UNI_R; 374 omap_writel(l, USB_TRANSCEIVER_CTRL); 375 } 376 377 /* external transceiver */ 378 if (cpu_is_omap15xx()) { 379 omap_cfg_reg(USB2_TXD); 380 omap_cfg_reg(USB2_TXEN); 381 omap_cfg_reg(USB2_SEO); 382 if (nwires != 3) 383 omap_cfg_reg(USB2_RCV); 384 /* there is no USB2_SPEED */ 385 } else if (cpu_is_omap16xx()) { 386 omap_cfg_reg(V6_USB2_TXD); 387 omap_cfg_reg(W9_USB2_TXEN); 388 omap_cfg_reg(W5_USB2_SE0); 389 if (nwires != 3) 390 omap_cfg_reg(Y5_USB2_RCV); 391 // FIXME omap_cfg_reg(USB2_SPEED); 392 } else { 393 pr_debug("usb%d cpu unrecognized\n", 1); 394 return 0; 395 } 396 397 // omap_cfg_reg(USB2_SUSP); 398 399 switch (nwires) { 400 case 2: 401 goto bad; 402 case 3: 403 syscon1 = 2; 404 break; 405 case 4: 406 syscon1 = 1; 407 break; 408 case 5: 409 goto bad; 410 case 6: 411 syscon1 = 3; 412 if (cpu_is_omap15xx()) { 413 omap_cfg_reg(USB2_VP); 414 omap_cfg_reg(USB2_VM); 415 } else { 416 u32 l; 417 418 omap_cfg_reg(AA9_USB2_VP); 419 omap_cfg_reg(R9_USB2_VM); 420 l = omap_readl(USB_TRANSCEIVER_CTRL); 421 l |= CONF_USB2_UNI_R; 422 omap_writel(l, USB_TRANSCEIVER_CTRL); 423 } 424 break; 425 default: 426 bad: 427 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", 428 2, nwires); 429 } 430 431 return syscon1 << 24; 432 } 433 434 #ifdef CONFIG_ARCH_OMAP15XX 435 436 /* ULPD_DPLL_CTRL */ 437 #define DPLL_IOB (1 << 13) 438 #define DPLL_PLL_ENABLE (1 << 4) 439 #define DPLL_LOCK (1 << 0) 440 441 /* ULPD_APLL_CTRL */ 442 #define APLL_NDPLL_SWITCH (1 << 0) 443 444 static void __init omap_1510_usb_init(struct omap_usb_config *config) 445 { 446 unsigned int val; 447 u16 w; 448 449 config->usb0_init(config->pins[0], is_usb0_device(config)); 450 config->usb1_init(config->pins[1]); 451 config->usb2_init(config->pins[2], 0); 452 453 val = omap_readl(MOD_CONF_CTRL_0) & ~(0x3f << 1); 454 val |= (config->hmc_mode << 1); 455 omap_writel(val, MOD_CONF_CTRL_0); 456 457 printk("USB: hmc %d", config->hmc_mode); 458 if (config->pins[0]) 459 printk(", usb0 %d wires%s", config->pins[0], 460 is_usb0_device(config) ? " (dev)" : ""); 461 if (config->pins[1]) 462 printk(", usb1 %d wires", config->pins[1]); 463 if (config->pins[2]) 464 printk(", usb2 %d wires", config->pins[2]); 465 printk("\n"); 466 467 /* use DPLL for 48 MHz function clock */ 468 pr_debug("APLL %04x DPLL %04x REQ %04x\n", omap_readw(ULPD_APLL_CTRL), 469 omap_readw(ULPD_DPLL_CTRL), omap_readw(ULPD_SOFT_REQ)); 470 471 w = omap_readw(ULPD_APLL_CTRL); 472 w &= ~APLL_NDPLL_SWITCH; 473 omap_writew(w, ULPD_APLL_CTRL); 474 475 w = omap_readw(ULPD_DPLL_CTRL); 476 w |= DPLL_IOB | DPLL_PLL_ENABLE; 477 omap_writew(w, ULPD_DPLL_CTRL); 478 479 w = omap_readw(ULPD_SOFT_REQ); 480 w |= SOFT_UDC_REQ | SOFT_DPLL_REQ; 481 omap_writew(w, ULPD_SOFT_REQ); 482 483 while (!(omap_readw(ULPD_DPLL_CTRL) & DPLL_LOCK)) 484 cpu_relax(); 485 486 #ifdef CONFIG_USB_GADGET_OMAP 487 if (config->register_dev) { 488 int status; 489 490 udc_device.dev.platform_data = config; 491 status = platform_device_register(&udc_device); 492 if (status) 493 pr_debug("can't register UDC device, %d\n", status); 494 /* udc driver gates 48MHz by D+ pullup */ 495 } 496 #endif 497 498 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) 499 if (config->register_host) { 500 int status; 501 502 ohci_device.dev.platform_data = config; 503 status = platform_device_register(&ohci_device); 504 if (status) 505 pr_debug("can't register OHCI device, %d\n", status); 506 /* hcd explicitly gates 48MHz */ 507 } 508 #endif 509 } 510 511 #else 512 static inline void omap_1510_usb_init(struct omap_usb_config *config) {} 513 #endif 514 515 void __init omap1_usb_init(struct omap_usb_config *pdata) 516 { 517 pdata->usb0_init = omap1_usb0_init; 518 pdata->usb1_init = omap1_usb1_init; 519 pdata->usb2_init = omap1_usb2_init; 520 udc_device_init(pdata); 521 ohci_device_init(pdata); 522 otg_device_init(pdata); 523 524 if (cpu_is_omap7xx() || cpu_is_omap16xx()) 525 omap_otg_init(pdata); 526 else if (cpu_is_omap15xx()) 527 omap_1510_usb_init(pdata); 528 else 529 printk(KERN_ERR "USB: No init for your chip yet\n"); 530 } 531