diff options
Diffstat (limited to 'drivers/usb/musb/musb_dsps.c')
-rw-r--r-- | drivers/usb/musb/musb_dsps.c | 105 |
1 files changed, 44 insertions, 61 deletions
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index a900c9877195..65d931a28a14 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c | |||
@@ -119,7 +119,7 @@ struct dsps_musb_wrapper { | |||
119 | unsigned iddig:5; | 119 | unsigned iddig:5; |
120 | unsigned iddig_mux:5; | 120 | unsigned iddig_mux:5; |
121 | /* miscellaneous stuff */ | 121 | /* miscellaneous stuff */ |
122 | u8 poll_seconds; | 122 | unsigned poll_timeout; |
123 | }; | 123 | }; |
124 | 124 | ||
125 | /* | 125 | /* |
@@ -225,9 +225,8 @@ static void dsps_musb_enable(struct musb *musb) | |||
225 | 225 | ||
226 | dsps_writel(reg_base, wrp->epintr_set, epmask); | 226 | dsps_writel(reg_base, wrp->epintr_set, epmask); |
227 | dsps_writel(reg_base, wrp->coreintr_set, coremask); | 227 | dsps_writel(reg_base, wrp->coreintr_set, coremask); |
228 | /* Force the DRVVBUS IRQ so we can start polling for ID change. */ | 228 | /* start polling for ID change. */ |
229 | dsps_writel(reg_base, wrp->coreintr_set, | 229 | mod_timer(&glue->timer, jiffies + msecs_to_jiffies(wrp->poll_timeout)); |
230 | (1 << wrp->drvvbus) << wrp->usb_shift); | ||
231 | dsps_musb_try_idle(musb, 0); | 230 | dsps_musb_try_idle(musb, 0); |
232 | } | 231 | } |
233 | 232 | ||
@@ -285,7 +284,8 @@ static void otg_timer(unsigned long _musb) | |||
285 | } | 284 | } |
286 | if (!(devctl & MUSB_DEVCTL_SESSION) && !skip_session) | 285 | if (!(devctl & MUSB_DEVCTL_SESSION) && !skip_session) |
287 | dsps_writeb(mregs, MUSB_DEVCTL, MUSB_DEVCTL_SESSION); | 286 | dsps_writeb(mregs, MUSB_DEVCTL, MUSB_DEVCTL_SESSION); |
288 | mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); | 287 | mod_timer(&glue->timer, jiffies + |
288 | msecs_to_jiffies(wrp->poll_timeout)); | ||
289 | break; | 289 | break; |
290 | case OTG_STATE_A_WAIT_VFALL: | 290 | case OTG_STATE_A_WAIT_VFALL: |
291 | musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; | 291 | musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; |
@@ -330,28 +330,6 @@ static irqreturn_t dsps_interrupt(int irq, void *hci) | |||
330 | 330 | ||
331 | dev_dbg(musb->controller, "usbintr (%x) epintr(%x)\n", | 331 | dev_dbg(musb->controller, "usbintr (%x) epintr(%x)\n", |
332 | usbintr, epintr); | 332 | usbintr, epintr); |
333 | /* | ||
334 | * DRVVBUS IRQs are the only proxy we have (a very poor one!) for | ||
335 | * DSPS IP's missing ID change IRQ. We need an ID change IRQ to | ||
336 | * switch appropriately between halves of the OTG state machine. | ||
337 | * Managing DEVCTL.SESSION per Mentor docs requires that we know its | ||
338 | * value but DEVCTL.BDEVICE is invalid without DEVCTL.SESSION set. | ||
339 | * Also, DRVVBUS pulses for SRP (but not at 5V) ... | ||
340 | */ | ||
341 | if (is_host_active(musb) && usbintr & MUSB_INTR_BABBLE) { | ||
342 | pr_info("CAUTION: musb: Babble Interrupt Occurred\n"); | ||
343 | |||
344 | /* | ||
345 | * When a babble condition occurs, the musb controller removes | ||
346 | * the session and is no longer in host mode. Hence, all | ||
347 | * devices connected to its root hub get disconnected. | ||
348 | * | ||
349 | * Hand this error down to the musb core isr, so it can | ||
350 | * recover. | ||
351 | */ | ||
352 | musb->int_usb = MUSB_INTR_BABBLE | MUSB_INTR_DISCONNECT; | ||
353 | musb->int_tx = musb->int_rx = 0; | ||
354 | } | ||
355 | 333 | ||
356 | if (usbintr & ((1 << wrp->drvvbus) << wrp->usb_shift)) { | 334 | if (usbintr & ((1 << wrp->drvvbus) << wrp->usb_shift)) { |
357 | int drvvbus = dsps_readl(reg_base, wrp->status); | 335 | int drvvbus = dsps_readl(reg_base, wrp->status); |
@@ -374,8 +352,8 @@ static irqreturn_t dsps_interrupt(int irq, void *hci) | |||
374 | */ | 352 | */ |
375 | musb->int_usb &= ~MUSB_INTR_VBUSERROR; | 353 | musb->int_usb &= ~MUSB_INTR_VBUSERROR; |
376 | musb->xceiv->otg->state = OTG_STATE_A_WAIT_VFALL; | 354 | musb->xceiv->otg->state = OTG_STATE_A_WAIT_VFALL; |
377 | mod_timer(&glue->timer, | 355 | mod_timer(&glue->timer, jiffies + |
378 | jiffies + wrp->poll_seconds * HZ); | 356 | msecs_to_jiffies(wrp->poll_timeout)); |
379 | WARNING("VBUS error workaround (delay coming)\n"); | 357 | WARNING("VBUS error workaround (delay coming)\n"); |
380 | } else if (drvvbus) { | 358 | } else if (drvvbus) { |
381 | MUSB_HST_MODE(musb); | 359 | MUSB_HST_MODE(musb); |
@@ -404,7 +382,8 @@ static irqreturn_t dsps_interrupt(int irq, void *hci) | |||
404 | /* Poll for ID change in OTG port mode */ | 382 | /* Poll for ID change in OTG port mode */ |
405 | if (musb->xceiv->otg->state == OTG_STATE_B_IDLE && | 383 | if (musb->xceiv->otg->state == OTG_STATE_B_IDLE && |
406 | musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) | 384 | musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) |
407 | mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); | 385 | mod_timer(&glue->timer, jiffies + |
386 | msecs_to_jiffies(wrp->poll_timeout)); | ||
408 | out: | 387 | out: |
409 | spin_unlock_irqrestore(&musb->lock, flags); | 388 | spin_unlock_irqrestore(&musb->lock, flags); |
410 | 389 | ||
@@ -453,7 +432,7 @@ static int dsps_musb_init(struct musb *musb) | |||
453 | musb->ctrl_base = reg_base; | 432 | musb->ctrl_base = reg_base; |
454 | 433 | ||
455 | /* NOP driver needs change if supporting dual instance */ | 434 | /* NOP driver needs change if supporting dual instance */ |
456 | musb->xceiv = devm_usb_get_phy_by_phandle(dev, "phys", 0); | 435 | musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent, "phys", 0); |
457 | if (IS_ERR(musb->xceiv)) | 436 | if (IS_ERR(musb->xceiv)) |
458 | return PTR_ERR(musb->xceiv); | 437 | return PTR_ERR(musb->xceiv); |
459 | 438 | ||
@@ -497,7 +476,7 @@ static int dsps_musb_init(struct musb *musb) | |||
497 | * logic enabled. | 476 | * logic enabled. |
498 | */ | 477 | */ |
499 | val = dsps_readb(musb->mregs, MUSB_BABBLE_CTL); | 478 | val = dsps_readb(musb->mregs, MUSB_BABBLE_CTL); |
500 | if (val == MUSB_BABBLE_RCV_DISABLE) { | 479 | if (val & MUSB_BABBLE_RCV_DISABLE) { |
501 | glue->sw_babble_enabled = true; | 480 | glue->sw_babble_enabled = true; |
502 | val |= MUSB_BABBLE_SW_SESSION_CTRL; | 481 | val |= MUSB_BABBLE_SW_SESSION_CTRL; |
503 | dsps_writeb(musb->mregs, MUSB_BABBLE_CTL, val); | 482 | dsps_writeb(musb->mregs, MUSB_BABBLE_CTL, val); |
@@ -571,7 +550,7 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode) | |||
571 | return 0; | 550 | return 0; |
572 | } | 551 | } |
573 | 552 | ||
574 | static bool sw_babble_control(struct musb *musb) | 553 | static bool dsps_sw_babble_control(struct musb *musb) |
575 | { | 554 | { |
576 | u8 babble_ctl; | 555 | u8 babble_ctl; |
577 | bool session_restart = false; | 556 | bool session_restart = false; |
@@ -622,37 +601,36 @@ static bool sw_babble_control(struct musb *musb) | |||
622 | return session_restart; | 601 | return session_restart; |
623 | } | 602 | } |
624 | 603 | ||
625 | static int dsps_musb_reset(struct musb *musb) | 604 | static int dsps_musb_recover(struct musb *musb) |
626 | { | 605 | { |
627 | struct device *dev = musb->controller; | 606 | struct device *dev = musb->controller; |
628 | struct dsps_glue *glue = dev_get_drvdata(dev->parent); | 607 | struct dsps_glue *glue = dev_get_drvdata(dev->parent); |
629 | const struct dsps_musb_wrapper *wrp = glue->wrp; | 608 | int session_restart = 0; |
630 | int session_restart = 0, error; | ||
631 | 609 | ||
632 | if (glue->sw_babble_enabled) | 610 | if (glue->sw_babble_enabled) |
633 | session_restart = sw_babble_control(musb); | 611 | session_restart = dsps_sw_babble_control(musb); |
634 | /* | 612 | else |
635 | * In case of new silicon version babble condition can be recovered | ||
636 | * without resetting the MUSB. But for older silicon versions, MUSB | ||
637 | * reset is needed | ||
638 | */ | ||
639 | if (session_restart || !glue->sw_babble_enabled) { | ||
640 | dev_info(musb->controller, "Restarting MUSB to recover from Babble\n"); | ||
641 | dsps_writel(musb->ctrl_base, wrp->control, (1 << wrp->reset)); | ||
642 | usleep_range(100, 200); | ||
643 | usb_phy_shutdown(musb->xceiv); | ||
644 | error = phy_power_off(musb->phy); | ||
645 | if (error) | ||
646 | dev_err(dev, "phy shutdown failed: %i\n", error); | ||
647 | usleep_range(100, 200); | ||
648 | usb_phy_init(musb->xceiv); | ||
649 | error = phy_power_on(musb->phy); | ||
650 | if (error) | ||
651 | dev_err(dev, "phy powerup failed: %i\n", error); | ||
652 | session_restart = 1; | 613 | session_restart = 1; |
614 | |||
615 | return session_restart ? 0 : -EPIPE; | ||
616 | } | ||
617 | |||
618 | /* Similar to am35x, dm81xx support only 32-bit read operation */ | ||
619 | static void dsps_read_fifo32(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) | ||
620 | { | ||
621 | void __iomem *fifo = hw_ep->fifo; | ||
622 | |||
623 | if (len >= 4) { | ||
624 | ioread32_rep(fifo, dst, len >> 2); | ||
625 | dst += len & ~0x03; | ||
626 | len &= 0x03; | ||
653 | } | 627 | } |
654 | 628 | ||
655 | return !session_restart; | 629 | /* Read any remaining 1 to 3 bytes */ |
630 | if (len > 0) { | ||
631 | u32 val = musb_readl(fifo, 0); | ||
632 | memcpy(dst, &val, len); | ||
633 | } | ||
656 | } | 634 | } |
657 | 635 | ||
658 | static struct musb_platform_ops dsps_ops = { | 636 | static struct musb_platform_ops dsps_ops = { |
@@ -665,7 +643,7 @@ static struct musb_platform_ops dsps_ops = { | |||
665 | 643 | ||
666 | .try_idle = dsps_musb_try_idle, | 644 | .try_idle = dsps_musb_try_idle, |
667 | .set_mode = dsps_musb_set_mode, | 645 | .set_mode = dsps_musb_set_mode, |
668 | .reset = dsps_musb_reset, | 646 | .recover = dsps_musb_recover, |
669 | }; | 647 | }; |
670 | 648 | ||
671 | static u64 musb_dmamask = DMA_BIT_MASK(32); | 649 | static u64 musb_dmamask = DMA_BIT_MASK(32); |
@@ -737,7 +715,6 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue, | |||
737 | musb->dev.parent = dev; | 715 | musb->dev.parent = dev; |
738 | musb->dev.dma_mask = &musb_dmamask; | 716 | musb->dev.dma_mask = &musb_dmamask; |
739 | musb->dev.coherent_dma_mask = musb_dmamask; | 717 | musb->dev.coherent_dma_mask = musb_dmamask; |
740 | musb->dev.of_node = of_node_get(dn); | ||
741 | 718 | ||
742 | glue->musb = musb; | 719 | glue->musb = musb; |
743 | 720 | ||
@@ -802,6 +779,9 @@ static int dsps_probe(struct platform_device *pdev) | |||
802 | } | 779 | } |
803 | wrp = match->data; | 780 | wrp = match->data; |
804 | 781 | ||
782 | if (of_device_is_compatible(pdev->dev.of_node, "ti,musb-dm816")) | ||
783 | dsps_ops.read_fifo = dsps_read_fifo32; | ||
784 | |||
805 | /* allocate glue */ | 785 | /* allocate glue */ |
806 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); | 786 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); |
807 | if (!glue) | 787 | if (!glue) |
@@ -873,12 +853,14 @@ static const struct dsps_musb_wrapper am33xx_driver_data = { | |||
873 | .rxep_shift = 16, | 853 | .rxep_shift = 16, |
874 | .rxep_mask = 0xfffe, | 854 | .rxep_mask = 0xfffe, |
875 | .rxep_bitmap = (0xfffe << 16), | 855 | .rxep_bitmap = (0xfffe << 16), |
876 | .poll_seconds = 2, | 856 | .poll_timeout = 2000, /* ms */ |
877 | }; | 857 | }; |
878 | 858 | ||
879 | static const struct of_device_id musb_dsps_of_match[] = { | 859 | static const struct of_device_id musb_dsps_of_match[] = { |
880 | { .compatible = "ti,musb-am33xx", | 860 | { .compatible = "ti,musb-am33xx", |
881 | .data = (void *) &am33xx_driver_data, }, | 861 | .data = &am33xx_driver_data, }, |
862 | { .compatible = "ti,musb-dm816", | ||
863 | .data = &am33xx_driver_data, }, | ||
882 | { }, | 864 | { }, |
883 | }; | 865 | }; |
884 | MODULE_DEVICE_TABLE(of, musb_dsps_of_match); | 866 | MODULE_DEVICE_TABLE(of, musb_dsps_of_match); |
@@ -929,7 +911,8 @@ static int dsps_resume(struct device *dev) | |||
929 | dsps_writel(mbase, wrp->rx_mode, glue->context.rx_mode); | 911 | dsps_writel(mbase, wrp->rx_mode, glue->context.rx_mode); |
930 | if (musb->xceiv->otg->state == OTG_STATE_B_IDLE && | 912 | if (musb->xceiv->otg->state == OTG_STATE_B_IDLE && |
931 | musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) | 913 | musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) |
932 | mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); | 914 | mod_timer(&glue->timer, jiffies + |
915 | msecs_to_jiffies(wrp->poll_timeout)); | ||
933 | 916 | ||
934 | return 0; | 917 | return 0; |
935 | } | 918 | } |