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