1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2005-2007 by Texas Instruments 4 * Some code has been taken from tusb6010.c 5 * Copyrights for that are attributable to: 6 * Copyright (C) 2006 Nokia Corporation 7 * Tony Lindgren <tony@atomide.com> 8 * 9 * This file is part of the Inventra Controller Driver for Linux. 10 */ 11 #ifndef __UBOOT__ 12 #include <linux/module.h> 13 #include <linux/kernel.h> 14 #include <linux/sched.h> 15 #include <linux/init.h> 16 #include <linux/list.h> 17 #include <linux/io.h> 18 #include <linux/platform_device.h> 19 #include <linux/dma-mapping.h> 20 #include <linux/pm_runtime.h> 21 #include <linux/err.h> 22 #include <linux/usb/musb-omap.h> 23 #else 24 #include <common.h> 25 #include <asm/omap_common.h> 26 #include <asm/omap_musb.h> 27 #include <twl4030.h> 28 #include <twl6030.h> 29 #include "linux-compat.h" 30 #endif 31 32 #include "musb_core.h" 33 #include "omap2430.h" 34 35 #ifndef __UBOOT__ 36 struct omap2430_glue { 37 struct device *dev; 38 struct platform_device *musb; 39 enum omap_musb_vbus_id_status status; 40 struct work_struct omap_musb_mailbox_work; 41 }; 42 #define glue_to_musb(g) platform_get_drvdata(g->musb) 43 44 struct omap2430_glue *_glue; 45 46 static struct timer_list musb_idle_timer; 47 48 static void musb_do_idle(unsigned long _musb) 49 { 50 struct musb *musb = (void *)_musb; 51 unsigned long flags; 52 u8 power; 53 u8 devctl; 54 55 spin_lock_irqsave(&musb->lock, flags); 56 57 switch (musb->xceiv->state) { 58 case OTG_STATE_A_WAIT_BCON: 59 60 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); 61 if (devctl & MUSB_DEVCTL_BDEVICE) { 62 musb->xceiv->state = OTG_STATE_B_IDLE; 63 MUSB_DEV_MODE(musb); 64 } else { 65 musb->xceiv->state = OTG_STATE_A_IDLE; 66 MUSB_HST_MODE(musb); 67 } 68 break; 69 case OTG_STATE_A_SUSPEND: 70 /* finish RESUME signaling? */ 71 if (musb->port1_status & MUSB_PORT_STAT_RESUME) { 72 power = musb_readb(musb->mregs, MUSB_POWER); 73 power &= ~MUSB_POWER_RESUME; 74 dev_dbg(musb->controller, "root port resume stopped, power %02x\n", power); 75 musb_writeb(musb->mregs, MUSB_POWER, power); 76 musb->is_active = 1; 77 musb->port1_status &= ~(USB_PORT_STAT_SUSPEND 78 | MUSB_PORT_STAT_RESUME); 79 musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16; 80 usb_hcd_poll_rh_status(musb_to_hcd(musb)); 81 /* NOTE: it might really be A_WAIT_BCON ... */ 82 musb->xceiv->state = OTG_STATE_A_HOST; 83 } 84 break; 85 case OTG_STATE_A_HOST: 86 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); 87 if (devctl & MUSB_DEVCTL_BDEVICE) 88 musb->xceiv->state = OTG_STATE_B_IDLE; 89 else 90 musb->xceiv->state = OTG_STATE_A_WAIT_BCON; 91 default: 92 break; 93 } 94 spin_unlock_irqrestore(&musb->lock, flags); 95 } 96 97 98 static void omap2430_musb_try_idle(struct musb *musb, unsigned long timeout) 99 { 100 unsigned long default_timeout = jiffies + msecs_to_jiffies(3); 101 static unsigned long last_timer; 102 103 if (timeout == 0) 104 timeout = default_timeout; 105 106 /* Never idle if active, or when VBUS timeout is not set as host */ 107 if (musb->is_active || ((musb->a_wait_bcon == 0) 108 && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) { 109 dev_dbg(musb->controller, "%s active, deleting timer\n", 110 otg_state_string(musb->xceiv->state)); 111 del_timer(&musb_idle_timer); 112 last_timer = jiffies; 113 return; 114 } 115 116 if (time_after(last_timer, timeout)) { 117 if (!timer_pending(&musb_idle_timer)) 118 last_timer = timeout; 119 else { 120 dev_dbg(musb->controller, "Longer idle timer already pending, ignoring\n"); 121 return; 122 } 123 } 124 last_timer = timeout; 125 126 dev_dbg(musb->controller, "%s inactive, for idle timer for %lu ms\n", 127 otg_state_string(musb->xceiv->state), 128 (unsigned long)jiffies_to_msecs(timeout - jiffies)); 129 mod_timer(&musb_idle_timer, timeout); 130 } 131 132 static void omap2430_musb_set_vbus(struct musb *musb, int is_on) 133 { 134 struct usb_otg *otg = musb->xceiv->otg; 135 u8 devctl; 136 unsigned long timeout = jiffies + msecs_to_jiffies(1000); 137 int ret = 1; 138 /* HDRC controls CPEN, but beware current surges during device 139 * connect. They can trigger transient overcurrent conditions 140 * that must be ignored. 141 */ 142 143 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); 144 145 if (is_on) { 146 if (musb->xceiv->state == OTG_STATE_A_IDLE) { 147 /* start the session */ 148 devctl |= MUSB_DEVCTL_SESSION; 149 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); 150 /* 151 * Wait for the musb to set as A device to enable the 152 * VBUS 153 */ 154 while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) { 155 156 cpu_relax(); 157 158 if (time_after(jiffies, timeout)) { 159 dev_err(musb->controller, 160 "configured as A device timeout"); 161 ret = -EINVAL; 162 break; 163 } 164 } 165 166 if (ret && otg->set_vbus) 167 otg_set_vbus(otg, 1); 168 } else { 169 musb->is_active = 1; 170 otg->default_a = 1; 171 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; 172 devctl |= MUSB_DEVCTL_SESSION; 173 MUSB_HST_MODE(musb); 174 } 175 } else { 176 musb->is_active = 0; 177 178 /* NOTE: we're skipping A_WAIT_VFALL -> A_IDLE and 179 * jumping right to B_IDLE... 180 */ 181 182 otg->default_a = 0; 183 musb->xceiv->state = OTG_STATE_B_IDLE; 184 devctl &= ~MUSB_DEVCTL_SESSION; 185 186 MUSB_DEV_MODE(musb); 187 } 188 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); 189 190 dev_dbg(musb->controller, "VBUS %s, devctl %02x " 191 /* otg %3x conf %08x prcm %08x */ "\n", 192 otg_state_string(musb->xceiv->state), 193 musb_readb(musb->mregs, MUSB_DEVCTL)); 194 } 195 196 static int omap2430_musb_set_mode(struct musb *musb, u8 musb_mode) 197 { 198 u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); 199 200 devctl |= MUSB_DEVCTL_SESSION; 201 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); 202 203 return 0; 204 } 205 #endif 206 207 static inline void omap2430_low_level_exit(struct musb *musb) 208 { 209 u32 l; 210 211 /* in any role */ 212 l = musb_readl(musb->mregs, OTG_FORCESTDBY); 213 l |= ENABLEFORCE; /* enable MSTANDBY */ 214 musb_writel(musb->mregs, OTG_FORCESTDBY, l); 215 } 216 217 static inline void omap2430_low_level_init(struct musb *musb) 218 { 219 u32 l; 220 221 l = musb_readl(musb->mregs, OTG_FORCESTDBY); 222 l &= ~ENABLEFORCE; /* disable MSTANDBY */ 223 musb_writel(musb->mregs, OTG_FORCESTDBY, l); 224 } 225 226 #ifndef __UBOOT__ 227 void omap_musb_mailbox(enum omap_musb_vbus_id_status status) 228 { 229 struct omap2430_glue *glue = _glue; 230 struct musb *musb = glue_to_musb(glue); 231 232 glue->status = status; 233 if (!musb) { 234 dev_err(glue->dev, "musb core is not yet ready\n"); 235 return; 236 } 237 238 schedule_work(&glue->omap_musb_mailbox_work); 239 } 240 EXPORT_SYMBOL_GPL(omap_musb_mailbox); 241 242 static void omap_musb_set_mailbox(struct omap2430_glue *glue) 243 { 244 struct musb *musb = glue_to_musb(glue); 245 struct device *dev = musb->controller; 246 struct musb_hdrc_platform_data *pdata = dev->platform_data; 247 struct omap_musb_board_data *data = pdata->board_data; 248 struct usb_otg *otg = musb->xceiv->otg; 249 250 switch (glue->status) { 251 case OMAP_MUSB_ID_GROUND: 252 dev_dbg(dev, "ID GND\n"); 253 254 otg->default_a = true; 255 musb->xceiv->state = OTG_STATE_A_IDLE; 256 musb->xceiv->last_event = USB_EVENT_ID; 257 if (!is_otg_enabled(musb) || musb->gadget_driver) { 258 pm_runtime_get_sync(dev); 259 usb_phy_init(musb->xceiv); 260 omap2430_musb_set_vbus(musb, 1); 261 } 262 break; 263 264 case OMAP_MUSB_VBUS_VALID: 265 dev_dbg(dev, "VBUS Connect\n"); 266 267 otg->default_a = false; 268 musb->xceiv->state = OTG_STATE_B_IDLE; 269 musb->xceiv->last_event = USB_EVENT_VBUS; 270 if (musb->gadget_driver) 271 pm_runtime_get_sync(dev); 272 usb_phy_init(musb->xceiv); 273 break; 274 275 case OMAP_MUSB_ID_FLOAT: 276 case OMAP_MUSB_VBUS_OFF: 277 dev_dbg(dev, "VBUS Disconnect\n"); 278 279 musb->xceiv->last_event = USB_EVENT_NONE; 280 if (is_otg_enabled(musb) || is_peripheral_enabled(musb)) 281 if (musb->gadget_driver) { 282 pm_runtime_mark_last_busy(dev); 283 pm_runtime_put_autosuspend(dev); 284 } 285 286 if (data->interface_type == MUSB_INTERFACE_UTMI) { 287 if (musb->xceiv->otg->set_vbus) 288 otg_set_vbus(musb->xceiv->otg, 0); 289 } 290 usb_phy_shutdown(musb->xceiv); 291 break; 292 default: 293 dev_dbg(dev, "ID float\n"); 294 } 295 } 296 297 298 static void omap_musb_mailbox_work(struct work_struct *mailbox_work) 299 { 300 struct omap2430_glue *glue = container_of(mailbox_work, 301 struct omap2430_glue, omap_musb_mailbox_work); 302 omap_musb_set_mailbox(glue); 303 } 304 #endif 305 306 static int omap2430_musb_init(struct musb *musb) 307 { 308 u32 l; 309 int status = 0; 310 unsigned long int start; 311 #ifndef __UBOOT__ 312 struct device *dev = musb->controller; 313 struct omap2430_glue *glue = dev_get_drvdata(dev->parent); 314 struct musb_hdrc_platform_data *plat = dev->platform_data; 315 struct omap_musb_board_data *data = plat->board_data; 316 #else 317 struct omap_musb_board_data *data = 318 (struct omap_musb_board_data *)musb->controller; 319 #endif 320 321 /* Reset the controller */ 322 musb_writel(musb->mregs, OTG_SYSCONFIG, SOFTRST); 323 324 start = get_timer(0); 325 326 while (1) { 327 l = musb_readl(musb->mregs, OTG_SYSCONFIG); 328 if ((l & SOFTRST) == 0) 329 break; 330 331 if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) { 332 dev_err(musb->controller, "MUSB reset is taking too long\n"); 333 return -ENODEV; 334 } 335 } 336 337 #ifndef __UBOOT__ 338 /* We require some kind of external transceiver, hooked 339 * up through ULPI. TWL4030-family PMICs include one, 340 * which needs a driver, drivers aren't always needed. 341 */ 342 musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); 343 if (IS_ERR_OR_NULL(musb->xceiv)) { 344 pr_err("HS USB OTG: no transceiver configured\n"); 345 return -ENODEV; 346 } 347 348 status = pm_runtime_get_sync(dev); 349 if (status < 0) { 350 dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status); 351 goto err1; 352 } 353 #endif 354 355 l = musb_readl(musb->mregs, OTG_INTERFSEL); 356 357 if (data->interface_type == MUSB_INTERFACE_UTMI) { 358 /* OMAP4 uses Internal PHY GS70 which uses UTMI interface */ 359 l &= ~ULPI_12PIN; /* Disable ULPI */ 360 l |= UTMI_8BIT; /* Enable UTMI */ 361 } else { 362 l |= ULPI_12PIN; 363 } 364 365 musb_writel(musb->mregs, OTG_INTERFSEL, l); 366 367 pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, " 368 "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n", 369 musb_readl(musb->mregs, OTG_REVISION), 370 musb_readl(musb->mregs, OTG_SYSCONFIG), 371 musb_readl(musb->mregs, OTG_SYSSTATUS), 372 musb_readl(musb->mregs, OTG_INTERFSEL), 373 musb_readl(musb->mregs, OTG_SIMENABLE)); 374 375 #ifndef __UBOOT__ 376 setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); 377 378 if (glue->status != OMAP_MUSB_UNKNOWN) 379 omap_musb_set_mailbox(glue); 380 381 pm_runtime_put_noidle(musb->controller); 382 #endif 383 return 0; 384 385 err1: 386 return status; 387 } 388 389 #ifndef __UBOOT__ 390 static void omap2430_musb_enable(struct musb *musb) 391 #else 392 static int omap2430_musb_enable(struct musb *musb) 393 #endif 394 { 395 #ifndef __UBOOT__ 396 u8 devctl; 397 unsigned long timeout = jiffies + msecs_to_jiffies(1000); 398 struct device *dev = musb->controller; 399 struct omap2430_glue *glue = dev_get_drvdata(dev->parent); 400 struct musb_hdrc_platform_data *pdata = dev->platform_data; 401 struct omap_musb_board_data *data = pdata->board_data; 402 403 switch (glue->status) { 404 405 case OMAP_MUSB_ID_GROUND: 406 usb_phy_init(musb->xceiv); 407 if (data->interface_type != MUSB_INTERFACE_UTMI) 408 break; 409 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); 410 /* start the session */ 411 devctl |= MUSB_DEVCTL_SESSION; 412 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); 413 while (musb_readb(musb->mregs, MUSB_DEVCTL) & 414 MUSB_DEVCTL_BDEVICE) { 415 cpu_relax(); 416 417 if (time_after(jiffies, timeout)) { 418 dev_err(dev, "configured as A device timeout"); 419 break; 420 } 421 } 422 break; 423 424 case OMAP_MUSB_VBUS_VALID: 425 usb_phy_init(musb->xceiv); 426 break; 427 428 default: 429 break; 430 } 431 #else 432 #ifdef CONFIG_TWL4030_USB 433 if (twl4030_usb_ulpi_init()) { 434 serial_printf("ERROR: %s Could not initialize PHY\n", 435 __PRETTY_FUNCTION__); 436 } 437 #endif 438 439 #ifdef CONFIG_TWL6030_POWER 440 twl6030_usb_device_settings(); 441 #endif 442 443 #ifdef CONFIG_OMAP44XX 444 u32 *usbotghs_control = (u32 *)((*ctrl)->control_usbotghs_ctrl); 445 *usbotghs_control = USBOTGHS_CONTROL_AVALID | 446 USBOTGHS_CONTROL_VBUSVALID | USBOTGHS_CONTROL_IDDIG; 447 #endif 448 449 return 0; 450 #endif 451 } 452 453 static void omap2430_musb_disable(struct musb *musb) 454 { 455 #ifndef __UBOOT__ 456 struct device *dev = musb->controller; 457 struct omap2430_glue *glue = dev_get_drvdata(dev->parent); 458 459 if (glue->status != OMAP_MUSB_UNKNOWN) 460 usb_phy_shutdown(musb->xceiv); 461 #endif 462 } 463 464 static int omap2430_musb_exit(struct musb *musb) 465 { 466 del_timer_sync(&musb_idle_timer); 467 468 omap2430_low_level_exit(musb); 469 470 return 0; 471 } 472 473 #ifndef __UBOOT__ 474 static const struct musb_platform_ops omap2430_ops = { 475 #else 476 const struct musb_platform_ops omap2430_ops = { 477 #endif 478 .init = omap2430_musb_init, 479 .exit = omap2430_musb_exit, 480 481 #ifndef __UBOOT__ 482 .set_mode = omap2430_musb_set_mode, 483 .try_idle = omap2430_musb_try_idle, 484 485 .set_vbus = omap2430_musb_set_vbus, 486 #endif 487 488 .enable = omap2430_musb_enable, 489 .disable = omap2430_musb_disable, 490 }; 491 492 #ifndef __UBOOT__ 493 static u64 omap2430_dmamask = DMA_BIT_MASK(32); 494 495 static int __devinit omap2430_probe(struct platform_device *pdev) 496 { 497 struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; 498 struct platform_device *musb; 499 struct omap2430_glue *glue; 500 int ret = -ENOMEM; 501 502 glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); 503 if (!glue) { 504 dev_err(&pdev->dev, "failed to allocate glue context\n"); 505 goto err0; 506 } 507 508 musb = platform_device_alloc("musb-hdrc", -1); 509 if (!musb) { 510 dev_err(&pdev->dev, "failed to allocate musb device\n"); 511 goto err0; 512 } 513 514 musb->dev.parent = &pdev->dev; 515 musb->dev.dma_mask = &omap2430_dmamask; 516 musb->dev.coherent_dma_mask = omap2430_dmamask; 517 518 glue->dev = &pdev->dev; 519 glue->musb = musb; 520 glue->status = OMAP_MUSB_UNKNOWN; 521 522 pdata->platform_ops = &omap2430_ops; 523 524 platform_set_drvdata(pdev, glue); 525 526 /* 527 * REVISIT if we ever have two instances of the wrapper, we will be 528 * in big trouble 529 */ 530 _glue = glue; 531 532 INIT_WORK(&glue->omap_musb_mailbox_work, omap_musb_mailbox_work); 533 534 ret = platform_device_add_resources(musb, pdev->resource, 535 pdev->num_resources); 536 if (ret) { 537 dev_err(&pdev->dev, "failed to add resources\n"); 538 goto err1; 539 } 540 541 ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); 542 if (ret) { 543 dev_err(&pdev->dev, "failed to add platform_data\n"); 544 goto err1; 545 } 546 547 pm_runtime_enable(&pdev->dev); 548 549 ret = platform_device_add(musb); 550 if (ret) { 551 dev_err(&pdev->dev, "failed to register musb device\n"); 552 goto err1; 553 } 554 555 return 0; 556 557 err1: 558 platform_device_put(musb); 559 560 err0: 561 return ret; 562 } 563 564 static int __devexit omap2430_remove(struct platform_device *pdev) 565 { 566 struct omap2430_glue *glue = platform_get_drvdata(pdev); 567 568 cancel_work_sync(&glue->omap_musb_mailbox_work); 569 platform_device_del(glue->musb); 570 platform_device_put(glue->musb); 571 572 return 0; 573 } 574 575 #ifdef CONFIG_PM 576 577 static int omap2430_runtime_suspend(struct device *dev) 578 { 579 struct omap2430_glue *glue = dev_get_drvdata(dev); 580 struct musb *musb = glue_to_musb(glue); 581 582 if (musb) { 583 musb->context.otg_interfsel = musb_readl(musb->mregs, 584 OTG_INTERFSEL); 585 586 omap2430_low_level_exit(musb); 587 usb_phy_set_suspend(musb->xceiv, 1); 588 } 589 590 return 0; 591 } 592 593 static int omap2430_runtime_resume(struct device *dev) 594 { 595 struct omap2430_glue *glue = dev_get_drvdata(dev); 596 struct musb *musb = glue_to_musb(glue); 597 598 if (musb) { 599 omap2430_low_level_init(musb); 600 musb_writel(musb->mregs, OTG_INTERFSEL, 601 musb->context.otg_interfsel); 602 603 usb_phy_set_suspend(musb->xceiv, 0); 604 } 605 606 return 0; 607 } 608 609 static struct dev_pm_ops omap2430_pm_ops = { 610 .runtime_suspend = omap2430_runtime_suspend, 611 .runtime_resume = omap2430_runtime_resume, 612 }; 613 614 #define DEV_PM_OPS (&omap2430_pm_ops) 615 #else 616 #define DEV_PM_OPS NULL 617 #endif 618 619 static struct platform_driver omap2430_driver = { 620 .probe = omap2430_probe, 621 .remove = __devexit_p(omap2430_remove), 622 .driver = { 623 .name = "musb-omap2430", 624 .pm = DEV_PM_OPS, 625 }, 626 }; 627 628 MODULE_DESCRIPTION("OMAP2PLUS MUSB Glue Layer"); 629 MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); 630 MODULE_LICENSE("GPL v2"); 631 632 static int __init omap2430_init(void) 633 { 634 return platform_driver_register(&omap2430_driver); 635 } 636 subsys_initcall(omap2430_init); 637 638 static void __exit omap2430_exit(void) 639 { 640 platform_driver_unregister(&omap2430_driver); 641 } 642 module_exit(omap2430_exit); 643 #endif 644