diff options
author | John Youn <johnyoun@synopsys.com> | 2016-02-23 22:55:00 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@kernel.org> | 2016-03-04 08:14:46 -0500 |
commit | b02038faa7f1b228983d05633c8345f826b20042 (patch) | |
tree | dec7103c71c8aafb22571d43eaf48553aae56e18 /drivers/usb/dwc2/core.c | |
parent | 58e52ff6a6c3ce964c71b2dd9f06be426f993524 (diff) |
usb: dwc2: Move host-specific core functions into hcd.c
Move host core initialization and host channel routines into hcd.c. This
allows these functions to only be compiled in host-enabled driver
configurations (DRD or host-only).
Tested-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Diffstat (limited to 'drivers/usb/dwc2/core.c')
-rw-r--r-- | drivers/usb/dwc2/core.c | 1776 |
1 files changed, 0 insertions, 1776 deletions
diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index d5091b91ba49..4135a5ff67ca 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c | |||
@@ -238,62 +238,6 @@ int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg) | |||
238 | return ret; | 238 | return ret; |
239 | } | 239 | } |
240 | 240 | ||
241 | /** | ||
242 | * dwc2_enable_common_interrupts() - Initializes the commmon interrupts, | ||
243 | * used in both device and host modes | ||
244 | * | ||
245 | * @hsotg: Programming view of the DWC_otg controller | ||
246 | */ | ||
247 | static void dwc2_enable_common_interrupts(struct dwc2_hsotg *hsotg) | ||
248 | { | ||
249 | u32 intmsk; | ||
250 | |||
251 | /* Clear any pending OTG Interrupts */ | ||
252 | dwc2_writel(0xffffffff, hsotg->regs + GOTGINT); | ||
253 | |||
254 | /* Clear any pending interrupts */ | ||
255 | dwc2_writel(0xffffffff, hsotg->regs + GINTSTS); | ||
256 | |||
257 | /* Enable the interrupts in the GINTMSK */ | ||
258 | intmsk = GINTSTS_MODEMIS | GINTSTS_OTGINT; | ||
259 | |||
260 | if (hsotg->core_params->dma_enable <= 0) | ||
261 | intmsk |= GINTSTS_RXFLVL; | ||
262 | if (hsotg->core_params->external_id_pin_ctl <= 0) | ||
263 | intmsk |= GINTSTS_CONIDSTSCHNG; | ||
264 | |||
265 | intmsk |= GINTSTS_WKUPINT | GINTSTS_USBSUSP | | ||
266 | GINTSTS_SESSREQINT; | ||
267 | |||
268 | dwc2_writel(intmsk, hsotg->regs + GINTMSK); | ||
269 | } | ||
270 | |||
271 | /* | ||
272 | * Initializes the FSLSPClkSel field of the HCFG register depending on the | ||
273 | * PHY type | ||
274 | */ | ||
275 | static void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg) | ||
276 | { | ||
277 | u32 hcfg, val; | ||
278 | |||
279 | if ((hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI && | ||
280 | hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED && | ||
281 | hsotg->core_params->ulpi_fs_ls > 0) || | ||
282 | hsotg->core_params->phy_type == DWC2_PHY_TYPE_PARAM_FS) { | ||
283 | /* Full speed PHY */ | ||
284 | val = HCFG_FSLSPCLKSEL_48_MHZ; | ||
285 | } else { | ||
286 | /* High speed PHY running at full speed or high speed */ | ||
287 | val = HCFG_FSLSPCLKSEL_30_60_MHZ; | ||
288 | } | ||
289 | |||
290 | dev_dbg(hsotg->dev, "Initializing HCFG.FSLSPClkSel to %08x\n", val); | ||
291 | hcfg = dwc2_readl(hsotg->regs + HCFG); | ||
292 | hcfg &= ~HCFG_FSLSPCLKSEL_MASK; | ||
293 | hcfg |= val << HCFG_FSLSPCLKSEL_SHIFT; | ||
294 | dwc2_writel(hcfg, hsotg->regs + HCFG); | ||
295 | } | ||
296 | |||
297 | /* | 241 | /* |
298 | * Do core a soft reset of the core. Be careful with this because it | 242 | * Do core a soft reset of the core. Be careful with this because it |
299 | * resets all the internal state machines of the core. | 243 | * resets all the internal state machines of the core. |
@@ -463,1726 +407,6 @@ int dwc2_core_reset_and_force_dr_mode(struct dwc2_hsotg *hsotg) | |||
463 | return 0; | 407 | return 0; |
464 | } | 408 | } |
465 | 409 | ||
466 | static int dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) | ||
467 | { | ||
468 | u32 usbcfg, i2cctl; | ||
469 | int retval = 0; | ||
470 | |||
471 | /* | ||
472 | * core_init() is now called on every switch so only call the | ||
473 | * following for the first time through | ||
474 | */ | ||
475 | if (select_phy) { | ||
476 | dev_dbg(hsotg->dev, "FS PHY selected\n"); | ||
477 | |||
478 | usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); | ||
479 | if (!(usbcfg & GUSBCFG_PHYSEL)) { | ||
480 | usbcfg |= GUSBCFG_PHYSEL; | ||
481 | dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); | ||
482 | |||
483 | /* Reset after a PHY select */ | ||
484 | retval = dwc2_core_reset_and_force_dr_mode(hsotg); | ||
485 | |||
486 | if (retval) { | ||
487 | dev_err(hsotg->dev, | ||
488 | "%s: Reset failed, aborting", __func__); | ||
489 | return retval; | ||
490 | } | ||
491 | } | ||
492 | } | ||
493 | |||
494 | /* | ||
495 | * Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS. Also | ||
496 | * do this on HNP Dev/Host mode switches (done in dev_init and | ||
497 | * host_init). | ||
498 | */ | ||
499 | if (dwc2_is_host_mode(hsotg)) | ||
500 | dwc2_init_fs_ls_pclk_sel(hsotg); | ||
501 | |||
502 | if (hsotg->core_params->i2c_enable > 0) { | ||
503 | dev_dbg(hsotg->dev, "FS PHY enabling I2C\n"); | ||
504 | |||
505 | /* Program GUSBCFG.OtgUtmiFsSel to I2C */ | ||
506 | usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); | ||
507 | usbcfg |= GUSBCFG_OTG_UTMI_FS_SEL; | ||
508 | dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); | ||
509 | |||
510 | /* Program GI2CCTL.I2CEn */ | ||
511 | i2cctl = dwc2_readl(hsotg->regs + GI2CCTL); | ||
512 | i2cctl &= ~GI2CCTL_I2CDEVADDR_MASK; | ||
513 | i2cctl |= 1 << GI2CCTL_I2CDEVADDR_SHIFT; | ||
514 | i2cctl &= ~GI2CCTL_I2CEN; | ||
515 | dwc2_writel(i2cctl, hsotg->regs + GI2CCTL); | ||
516 | i2cctl |= GI2CCTL_I2CEN; | ||
517 | dwc2_writel(i2cctl, hsotg->regs + GI2CCTL); | ||
518 | } | ||
519 | |||
520 | return retval; | ||
521 | } | ||
522 | |||
523 | static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) | ||
524 | { | ||
525 | u32 usbcfg, usbcfg_old; | ||
526 | int retval = 0; | ||
527 | |||
528 | if (!select_phy) | ||
529 | return 0; | ||
530 | |||
531 | usbcfg = usbcfg_old = dwc2_readl(hsotg->regs + GUSBCFG); | ||
532 | |||
533 | /* | ||
534 | * HS PHY parameters. These parameters are preserved during soft reset | ||
535 | * so only program the first time. Do a soft reset immediately after | ||
536 | * setting phyif. | ||
537 | */ | ||
538 | switch (hsotg->core_params->phy_type) { | ||
539 | case DWC2_PHY_TYPE_PARAM_ULPI: | ||
540 | /* ULPI interface */ | ||
541 | dev_dbg(hsotg->dev, "HS ULPI PHY selected\n"); | ||
542 | usbcfg |= GUSBCFG_ULPI_UTMI_SEL; | ||
543 | usbcfg &= ~(GUSBCFG_PHYIF16 | GUSBCFG_DDRSEL); | ||
544 | if (hsotg->core_params->phy_ulpi_ddr > 0) | ||
545 | usbcfg |= GUSBCFG_DDRSEL; | ||
546 | break; | ||
547 | case DWC2_PHY_TYPE_PARAM_UTMI: | ||
548 | /* UTMI+ interface */ | ||
549 | dev_dbg(hsotg->dev, "HS UTMI+ PHY selected\n"); | ||
550 | usbcfg &= ~(GUSBCFG_ULPI_UTMI_SEL | GUSBCFG_PHYIF16); | ||
551 | if (hsotg->core_params->phy_utmi_width == 16) | ||
552 | usbcfg |= GUSBCFG_PHYIF16; | ||
553 | break; | ||
554 | default: | ||
555 | dev_err(hsotg->dev, "FS PHY selected at HS!\n"); | ||
556 | break; | ||
557 | } | ||
558 | |||
559 | if (usbcfg != usbcfg_old) { | ||
560 | dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); | ||
561 | |||
562 | /* Reset after setting the PHY parameters */ | ||
563 | retval = dwc2_core_reset_and_force_dr_mode(hsotg); | ||
564 | if (retval) { | ||
565 | dev_err(hsotg->dev, | ||
566 | "%s: Reset failed, aborting", __func__); | ||
567 | return retval; | ||
568 | } | ||
569 | } | ||
570 | |||
571 | return retval; | ||
572 | } | ||
573 | |||
574 | static int dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) | ||
575 | { | ||
576 | u32 usbcfg; | ||
577 | int retval = 0; | ||
578 | |||
579 | if (hsotg->core_params->speed == DWC2_SPEED_PARAM_FULL && | ||
580 | hsotg->core_params->phy_type == DWC2_PHY_TYPE_PARAM_FS) { | ||
581 | /* If FS mode with FS PHY */ | ||
582 | retval = dwc2_fs_phy_init(hsotg, select_phy); | ||
583 | if (retval) | ||
584 | return retval; | ||
585 | } else { | ||
586 | /* High speed PHY */ | ||
587 | retval = dwc2_hs_phy_init(hsotg, select_phy); | ||
588 | if (retval) | ||
589 | return retval; | ||
590 | } | ||
591 | |||
592 | if (hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI && | ||
593 | hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED && | ||
594 | hsotg->core_params->ulpi_fs_ls > 0) { | ||
595 | dev_dbg(hsotg->dev, "Setting ULPI FSLS\n"); | ||
596 | usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); | ||
597 | usbcfg |= GUSBCFG_ULPI_FS_LS; | ||
598 | usbcfg |= GUSBCFG_ULPI_CLK_SUSP_M; | ||
599 | dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); | ||
600 | } else { | ||
601 | usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); | ||
602 | usbcfg &= ~GUSBCFG_ULPI_FS_LS; | ||
603 | usbcfg &= ~GUSBCFG_ULPI_CLK_SUSP_M; | ||
604 | dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); | ||
605 | } | ||
606 | |||
607 | return retval; | ||
608 | } | ||
609 | |||
610 | static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg) | ||
611 | { | ||
612 | u32 ahbcfg = dwc2_readl(hsotg->regs + GAHBCFG); | ||
613 | |||
614 | switch (hsotg->hw_params.arch) { | ||
615 | case GHWCFG2_EXT_DMA_ARCH: | ||
616 | dev_err(hsotg->dev, "External DMA Mode not supported\n"); | ||
617 | return -EINVAL; | ||
618 | |||
619 | case GHWCFG2_INT_DMA_ARCH: | ||
620 | dev_dbg(hsotg->dev, "Internal DMA Mode\n"); | ||
621 | if (hsotg->core_params->ahbcfg != -1) { | ||
622 | ahbcfg &= GAHBCFG_CTRL_MASK; | ||
623 | ahbcfg |= hsotg->core_params->ahbcfg & | ||
624 | ~GAHBCFG_CTRL_MASK; | ||
625 | } | ||
626 | break; | ||
627 | |||
628 | case GHWCFG2_SLAVE_ONLY_ARCH: | ||
629 | default: | ||
630 | dev_dbg(hsotg->dev, "Slave Only Mode\n"); | ||
631 | break; | ||
632 | } | ||
633 | |||
634 | dev_dbg(hsotg->dev, "dma_enable:%d dma_desc_enable:%d\n", | ||
635 | hsotg->core_params->dma_enable, | ||
636 | hsotg->core_params->dma_desc_enable); | ||
637 | |||
638 | if (hsotg->core_params->dma_enable > 0) { | ||
639 | if (hsotg->core_params->dma_desc_enable > 0) | ||
640 | dev_dbg(hsotg->dev, "Using Descriptor DMA mode\n"); | ||
641 | else | ||
642 | dev_dbg(hsotg->dev, "Using Buffer DMA mode\n"); | ||
643 | } else { | ||
644 | dev_dbg(hsotg->dev, "Using Slave mode\n"); | ||
645 | hsotg->core_params->dma_desc_enable = 0; | ||
646 | } | ||
647 | |||
648 | if (hsotg->core_params->dma_enable > 0) | ||
649 | ahbcfg |= GAHBCFG_DMA_EN; | ||
650 | |||
651 | dwc2_writel(ahbcfg, hsotg->regs + GAHBCFG); | ||
652 | |||
653 | return 0; | ||
654 | } | ||
655 | |||
656 | static void dwc2_gusbcfg_init(struct dwc2_hsotg *hsotg) | ||
657 | { | ||
658 | u32 usbcfg; | ||
659 | |||
660 | usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); | ||
661 | usbcfg &= ~(GUSBCFG_HNPCAP | GUSBCFG_SRPCAP); | ||
662 | |||
663 | switch (hsotg->hw_params.op_mode) { | ||
664 | case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE: | ||
665 | if (hsotg->core_params->otg_cap == | ||
666 | DWC2_CAP_PARAM_HNP_SRP_CAPABLE) | ||
667 | usbcfg |= GUSBCFG_HNPCAP; | ||
668 | if (hsotg->core_params->otg_cap != | ||
669 | DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE) | ||
670 | usbcfg |= GUSBCFG_SRPCAP; | ||
671 | break; | ||
672 | |||
673 | case GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE: | ||
674 | case GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE: | ||
675 | case GHWCFG2_OP_MODE_SRP_CAPABLE_HOST: | ||
676 | if (hsotg->core_params->otg_cap != | ||
677 | DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE) | ||
678 | usbcfg |= GUSBCFG_SRPCAP; | ||
679 | break; | ||
680 | |||
681 | case GHWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE: | ||
682 | case GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE: | ||
683 | case GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST: | ||
684 | default: | ||
685 | break; | ||
686 | } | ||
687 | |||
688 | dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); | ||
689 | } | ||
690 | |||
691 | /** | ||
692 | * dwc2_core_init() - Initializes the DWC_otg controller registers and | ||
693 | * prepares the core for device mode or host mode operation | ||
694 | * | ||
695 | * @hsotg: Programming view of the DWC_otg controller | ||
696 | * @initial_setup: If true then this is the first init for this instance. | ||
697 | */ | ||
698 | int dwc2_core_init(struct dwc2_hsotg *hsotg, bool initial_setup) | ||
699 | { | ||
700 | u32 usbcfg, otgctl; | ||
701 | int retval; | ||
702 | |||
703 | dev_dbg(hsotg->dev, "%s(%p)\n", __func__, hsotg); | ||
704 | |||
705 | usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); | ||
706 | |||
707 | /* Set ULPI External VBUS bit if needed */ | ||
708 | usbcfg &= ~GUSBCFG_ULPI_EXT_VBUS_DRV; | ||
709 | if (hsotg->core_params->phy_ulpi_ext_vbus == | ||
710 | DWC2_PHY_ULPI_EXTERNAL_VBUS) | ||
711 | usbcfg |= GUSBCFG_ULPI_EXT_VBUS_DRV; | ||
712 | |||
713 | /* Set external TS Dline pulsing bit if needed */ | ||
714 | usbcfg &= ~GUSBCFG_TERMSELDLPULSE; | ||
715 | if (hsotg->core_params->ts_dline > 0) | ||
716 | usbcfg |= GUSBCFG_TERMSELDLPULSE; | ||
717 | |||
718 | dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); | ||
719 | |||
720 | /* | ||
721 | * Reset the Controller | ||
722 | * | ||
723 | * We only need to reset the controller if this is a re-init. | ||
724 | * For the first init we know for sure that earlier code reset us (it | ||
725 | * needed to in order to properly detect various parameters). | ||
726 | */ | ||
727 | if (!initial_setup) { | ||
728 | retval = dwc2_core_reset_and_force_dr_mode(hsotg); | ||
729 | if (retval) { | ||
730 | dev_err(hsotg->dev, "%s(): Reset failed, aborting\n", | ||
731 | __func__); | ||
732 | return retval; | ||
733 | } | ||
734 | } | ||
735 | |||
736 | /* | ||
737 | * This needs to happen in FS mode before any other programming occurs | ||
738 | */ | ||
739 | retval = dwc2_phy_init(hsotg, initial_setup); | ||
740 | if (retval) | ||
741 | return retval; | ||
742 | |||
743 | /* Program the GAHBCFG Register */ | ||
744 | retval = dwc2_gahbcfg_init(hsotg); | ||
745 | if (retval) | ||
746 | return retval; | ||
747 | |||
748 | /* Program the GUSBCFG register */ | ||
749 | dwc2_gusbcfg_init(hsotg); | ||
750 | |||
751 | /* Program the GOTGCTL register */ | ||
752 | otgctl = dwc2_readl(hsotg->regs + GOTGCTL); | ||
753 | otgctl &= ~GOTGCTL_OTGVER; | ||
754 | if (hsotg->core_params->otg_ver > 0) | ||
755 | otgctl |= GOTGCTL_OTGVER; | ||
756 | dwc2_writel(otgctl, hsotg->regs + GOTGCTL); | ||
757 | dev_dbg(hsotg->dev, "OTG VER PARAM: %d\n", hsotg->core_params->otg_ver); | ||
758 | |||
759 | /* Clear the SRP success bit for FS-I2c */ | ||
760 | hsotg->srp_success = 0; | ||
761 | |||
762 | /* Enable common interrupts */ | ||
763 | dwc2_enable_common_interrupts(hsotg); | ||
764 | |||
765 | /* | ||
766 | * Do device or host initialization based on mode during PCD and | ||
767 | * HCD initialization | ||
768 | */ | ||
769 | if (dwc2_is_host_mode(hsotg)) { | ||
770 | dev_dbg(hsotg->dev, "Host Mode\n"); | ||
771 | hsotg->op_state = OTG_STATE_A_HOST; | ||
772 | } else { | ||
773 | dev_dbg(hsotg->dev, "Device Mode\n"); | ||
774 | hsotg->op_state = OTG_STATE_B_PERIPHERAL; | ||
775 | } | ||
776 | |||
777 | return 0; | ||
778 | } | ||
779 | |||
780 | /** | ||
781 | * dwc2_enable_host_interrupts() - Enables the Host mode interrupts | ||
782 | * | ||
783 | * @hsotg: Programming view of DWC_otg controller | ||
784 | */ | ||
785 | void dwc2_enable_host_interrupts(struct dwc2_hsotg *hsotg) | ||
786 | { | ||
787 | u32 intmsk; | ||
788 | |||
789 | dev_dbg(hsotg->dev, "%s()\n", __func__); | ||
790 | |||
791 | /* Disable all interrupts */ | ||
792 | dwc2_writel(0, hsotg->regs + GINTMSK); | ||
793 | dwc2_writel(0, hsotg->regs + HAINTMSK); | ||
794 | |||
795 | /* Enable the common interrupts */ | ||
796 | dwc2_enable_common_interrupts(hsotg); | ||
797 | |||
798 | /* Enable host mode interrupts without disturbing common interrupts */ | ||
799 | intmsk = dwc2_readl(hsotg->regs + GINTMSK); | ||
800 | intmsk |= GINTSTS_DISCONNINT | GINTSTS_PRTINT | GINTSTS_HCHINT; | ||
801 | dwc2_writel(intmsk, hsotg->regs + GINTMSK); | ||
802 | } | ||
803 | |||
804 | /** | ||
805 | * dwc2_disable_host_interrupts() - Disables the Host Mode interrupts | ||
806 | * | ||
807 | * @hsotg: Programming view of DWC_otg controller | ||
808 | */ | ||
809 | void dwc2_disable_host_interrupts(struct dwc2_hsotg *hsotg) | ||
810 | { | ||
811 | u32 intmsk = dwc2_readl(hsotg->regs + GINTMSK); | ||
812 | |||
813 | /* Disable host mode interrupts without disturbing common interrupts */ | ||
814 | intmsk &= ~(GINTSTS_SOF | GINTSTS_PRTINT | GINTSTS_HCHINT | | ||
815 | GINTSTS_PTXFEMP | GINTSTS_NPTXFEMP | GINTSTS_DISCONNINT); | ||
816 | dwc2_writel(intmsk, hsotg->regs + GINTMSK); | ||
817 | } | ||
818 | |||
819 | /* | ||
820 | * dwc2_calculate_dynamic_fifo() - Calculates the default fifo size | ||
821 | * For system that have a total fifo depth that is smaller than the default | ||
822 | * RX + TX fifo size. | ||
823 | * | ||
824 | * @hsotg: Programming view of DWC_otg controller | ||
825 | */ | ||
826 | static void dwc2_calculate_dynamic_fifo(struct dwc2_hsotg *hsotg) | ||
827 | { | ||
828 | struct dwc2_core_params *params = hsotg->core_params; | ||
829 | struct dwc2_hw_params *hw = &hsotg->hw_params; | ||
830 | u32 rxfsiz, nptxfsiz, ptxfsiz, total_fifo_size; | ||
831 | |||
832 | total_fifo_size = hw->total_fifo_size; | ||
833 | rxfsiz = params->host_rx_fifo_size; | ||
834 | nptxfsiz = params->host_nperio_tx_fifo_size; | ||
835 | ptxfsiz = params->host_perio_tx_fifo_size; | ||
836 | |||
837 | /* | ||
838 | * Will use Method 2 defined in the DWC2 spec: minimum FIFO depth | ||
839 | * allocation with support for high bandwidth endpoints. Synopsys | ||
840 | * defines MPS(Max Packet size) for a periodic EP=1024, and for | ||
841 | * non-periodic as 512. | ||
842 | */ | ||
843 | if (total_fifo_size < (rxfsiz + nptxfsiz + ptxfsiz)) { | ||
844 | /* | ||
845 | * For Buffer DMA mode/Scatter Gather DMA mode | ||
846 | * 2 * ((Largest Packet size / 4) + 1 + 1) + n | ||
847 | * with n = number of host channel. | ||
848 | * 2 * ((1024/4) + 2) = 516 | ||
849 | */ | ||
850 | rxfsiz = 516 + hw->host_channels; | ||
851 | |||
852 | /* | ||
853 | * min non-periodic tx fifo depth | ||
854 | * 2 * (largest non-periodic USB packet used / 4) | ||
855 | * 2 * (512/4) = 256 | ||
856 | */ | ||
857 | nptxfsiz = 256; | ||
858 | |||
859 | /* | ||
860 | * min periodic tx fifo depth | ||
861 | * (largest packet size*MC)/4 | ||
862 | * (1024 * 3)/4 = 768 | ||
863 | */ | ||
864 | ptxfsiz = 768; | ||
865 | |||
866 | params->host_rx_fifo_size = rxfsiz; | ||
867 | params->host_nperio_tx_fifo_size = nptxfsiz; | ||
868 | params->host_perio_tx_fifo_size = ptxfsiz; | ||
869 | } | ||
870 | |||
871 | /* | ||
872 | * If the summation of RX, NPTX and PTX fifo sizes is still | ||
873 | * bigger than the total_fifo_size, then we have a problem. | ||
874 | * | ||
875 | * We won't be able to allocate as many endpoints. Right now, | ||
876 | * we're just printing an error message, but ideally this FIFO | ||
877 | * allocation algorithm would be improved in the future. | ||
878 | * | ||
879 | * FIXME improve this FIFO allocation algorithm. | ||
880 | */ | ||
881 | if (unlikely(total_fifo_size < (rxfsiz + nptxfsiz + ptxfsiz))) | ||
882 | dev_err(hsotg->dev, "invalid fifo sizes\n"); | ||
883 | } | ||
884 | |||
885 | static void dwc2_config_fifos(struct dwc2_hsotg *hsotg) | ||
886 | { | ||
887 | struct dwc2_core_params *params = hsotg->core_params; | ||
888 | u32 nptxfsiz, hptxfsiz, dfifocfg, grxfsiz; | ||
889 | |||
890 | if (!params->enable_dynamic_fifo) | ||
891 | return; | ||
892 | |||
893 | dwc2_calculate_dynamic_fifo(hsotg); | ||
894 | |||
895 | /* Rx FIFO */ | ||
896 | grxfsiz = dwc2_readl(hsotg->regs + GRXFSIZ); | ||
897 | dev_dbg(hsotg->dev, "initial grxfsiz=%08x\n", grxfsiz); | ||
898 | grxfsiz &= ~GRXFSIZ_DEPTH_MASK; | ||
899 | grxfsiz |= params->host_rx_fifo_size << | ||
900 | GRXFSIZ_DEPTH_SHIFT & GRXFSIZ_DEPTH_MASK; | ||
901 | dwc2_writel(grxfsiz, hsotg->regs + GRXFSIZ); | ||
902 | dev_dbg(hsotg->dev, "new grxfsiz=%08x\n", | ||
903 | dwc2_readl(hsotg->regs + GRXFSIZ)); | ||
904 | |||
905 | /* Non-periodic Tx FIFO */ | ||
906 | dev_dbg(hsotg->dev, "initial gnptxfsiz=%08x\n", | ||
907 | dwc2_readl(hsotg->regs + GNPTXFSIZ)); | ||
908 | nptxfsiz = params->host_nperio_tx_fifo_size << | ||
909 | FIFOSIZE_DEPTH_SHIFT & FIFOSIZE_DEPTH_MASK; | ||
910 | nptxfsiz |= params->host_rx_fifo_size << | ||
911 | FIFOSIZE_STARTADDR_SHIFT & FIFOSIZE_STARTADDR_MASK; | ||
912 | dwc2_writel(nptxfsiz, hsotg->regs + GNPTXFSIZ); | ||
913 | dev_dbg(hsotg->dev, "new gnptxfsiz=%08x\n", | ||
914 | dwc2_readl(hsotg->regs + GNPTXFSIZ)); | ||
915 | |||
916 | /* Periodic Tx FIFO */ | ||
917 | dev_dbg(hsotg->dev, "initial hptxfsiz=%08x\n", | ||
918 | dwc2_readl(hsotg->regs + HPTXFSIZ)); | ||
919 | hptxfsiz = params->host_perio_tx_fifo_size << | ||
920 | FIFOSIZE_DEPTH_SHIFT & FIFOSIZE_DEPTH_MASK; | ||
921 | hptxfsiz |= (params->host_rx_fifo_size + | ||
922 | params->host_nperio_tx_fifo_size) << | ||
923 | FIFOSIZE_STARTADDR_SHIFT & FIFOSIZE_STARTADDR_MASK; | ||
924 | dwc2_writel(hptxfsiz, hsotg->regs + HPTXFSIZ); | ||
925 | dev_dbg(hsotg->dev, "new hptxfsiz=%08x\n", | ||
926 | dwc2_readl(hsotg->regs + HPTXFSIZ)); | ||
927 | |||
928 | if (hsotg->core_params->en_multiple_tx_fifo > 0 && | ||
929 | hsotg->hw_params.snpsid <= DWC2_CORE_REV_2_94a) { | ||
930 | /* | ||
931 | * Global DFIFOCFG calculation for Host mode - | ||
932 | * include RxFIFO, NPTXFIFO and HPTXFIFO | ||
933 | */ | ||
934 | dfifocfg = dwc2_readl(hsotg->regs + GDFIFOCFG); | ||
935 | dfifocfg &= ~GDFIFOCFG_EPINFOBASE_MASK; | ||
936 | dfifocfg |= (params->host_rx_fifo_size + | ||
937 | params->host_nperio_tx_fifo_size + | ||
938 | params->host_perio_tx_fifo_size) << | ||
939 | GDFIFOCFG_EPINFOBASE_SHIFT & | ||
940 | GDFIFOCFG_EPINFOBASE_MASK; | ||
941 | dwc2_writel(dfifocfg, hsotg->regs + GDFIFOCFG); | ||
942 | } | ||
943 | } | ||
944 | |||
945 | /** | ||
946 | * dwc2_core_host_init() - Initializes the DWC_otg controller registers for | ||
947 | * Host mode | ||
948 | * | ||
949 | * @hsotg: Programming view of DWC_otg controller | ||
950 | * | ||
951 | * This function flushes the Tx and Rx FIFOs and flushes any entries in the | ||
952 | * request queues. Host channels are reset to ensure that they are ready for | ||
953 | * performing transfers. | ||
954 | */ | ||
955 | void dwc2_core_host_init(struct dwc2_hsotg *hsotg) | ||
956 | { | ||
957 | u32 hcfg, hfir, otgctl; | ||
958 | |||
959 | dev_dbg(hsotg->dev, "%s(%p)\n", __func__, hsotg); | ||
960 | |||
961 | /* Restart the Phy Clock */ | ||
962 | dwc2_writel(0, hsotg->regs + PCGCTL); | ||
963 | |||
964 | /* Initialize Host Configuration Register */ | ||
965 | dwc2_init_fs_ls_pclk_sel(hsotg); | ||
966 | if (hsotg->core_params->speed == DWC2_SPEED_PARAM_FULL) { | ||
967 | hcfg = dwc2_readl(hsotg->regs + HCFG); | ||
968 | hcfg |= HCFG_FSLSSUPP; | ||
969 | dwc2_writel(hcfg, hsotg->regs + HCFG); | ||
970 | } | ||
971 | |||
972 | /* | ||
973 | * This bit allows dynamic reloading of the HFIR register during | ||
974 | * runtime. This bit needs to be programmed during initial configuration | ||
975 | * and its value must not be changed during runtime. | ||
976 | */ | ||
977 | if (hsotg->core_params->reload_ctl > 0) { | ||
978 | hfir = dwc2_readl(hsotg->regs + HFIR); | ||
979 | hfir |= HFIR_RLDCTRL; | ||
980 | dwc2_writel(hfir, hsotg->regs + HFIR); | ||
981 | } | ||
982 | |||
983 | if (hsotg->core_params->dma_desc_enable > 0) { | ||
984 | u32 op_mode = hsotg->hw_params.op_mode; | ||
985 | if (hsotg->hw_params.snpsid < DWC2_CORE_REV_2_90a || | ||
986 | !hsotg->hw_params.dma_desc_enable || | ||
987 | op_mode == GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE || | ||
988 | op_mode == GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE || | ||
989 | op_mode == GHWCFG2_OP_MODE_UNDEFINED) { | ||
990 | dev_err(hsotg->dev, | ||
991 | "Hardware does not support descriptor DMA mode -\n"); | ||
992 | dev_err(hsotg->dev, | ||
993 | "falling back to buffer DMA mode.\n"); | ||
994 | hsotg->core_params->dma_desc_enable = 0; | ||
995 | } else { | ||
996 | hcfg = dwc2_readl(hsotg->regs + HCFG); | ||
997 | hcfg |= HCFG_DESCDMA; | ||
998 | dwc2_writel(hcfg, hsotg->regs + HCFG); | ||
999 | } | ||
1000 | } | ||
1001 | |||
1002 | /* Configure data FIFO sizes */ | ||
1003 | dwc2_config_fifos(hsotg); | ||
1004 | |||
1005 | /* TODO - check this */ | ||
1006 | /* Clear Host Set HNP Enable in the OTG Control Register */ | ||
1007 | otgctl = dwc2_readl(hsotg->regs + GOTGCTL); | ||
1008 | otgctl &= ~GOTGCTL_HSTSETHNPEN; | ||
1009 | dwc2_writel(otgctl, hsotg->regs + GOTGCTL); | ||
1010 | |||
1011 | /* Make sure the FIFOs are flushed */ | ||
1012 | dwc2_flush_tx_fifo(hsotg, 0x10 /* all TX FIFOs */); | ||
1013 | dwc2_flush_rx_fifo(hsotg); | ||
1014 | |||
1015 | /* Clear Host Set HNP Enable in the OTG Control Register */ | ||
1016 | otgctl = dwc2_readl(hsotg->regs + GOTGCTL); | ||
1017 | otgctl &= ~GOTGCTL_HSTSETHNPEN; | ||
1018 | dwc2_writel(otgctl, hsotg->regs + GOTGCTL); | ||
1019 | |||
1020 | if (hsotg->core_params->dma_desc_enable <= 0) { | ||
1021 | int num_channels, i; | ||
1022 | u32 hcchar; | ||
1023 | |||
1024 | /* Flush out any leftover queued requests */ | ||
1025 | num_channels = hsotg->core_params->host_channels; | ||
1026 | for (i = 0; i < num_channels; i++) { | ||
1027 | hcchar = dwc2_readl(hsotg->regs + HCCHAR(i)); | ||
1028 | hcchar &= ~HCCHAR_CHENA; | ||
1029 | hcchar |= HCCHAR_CHDIS; | ||
1030 | hcchar &= ~HCCHAR_EPDIR; | ||
1031 | dwc2_writel(hcchar, hsotg->regs + HCCHAR(i)); | ||
1032 | } | ||
1033 | |||
1034 | /* Halt all channels to put them into a known state */ | ||
1035 | for (i = 0; i < num_channels; i++) { | ||
1036 | int count = 0; | ||
1037 | |||
1038 | hcchar = dwc2_readl(hsotg->regs + HCCHAR(i)); | ||
1039 | hcchar |= HCCHAR_CHENA | HCCHAR_CHDIS; | ||
1040 | hcchar &= ~HCCHAR_EPDIR; | ||
1041 | dwc2_writel(hcchar, hsotg->regs + HCCHAR(i)); | ||
1042 | dev_dbg(hsotg->dev, "%s: Halt channel %d\n", | ||
1043 | __func__, i); | ||
1044 | do { | ||
1045 | hcchar = dwc2_readl(hsotg->regs + HCCHAR(i)); | ||
1046 | if (++count > 1000) { | ||
1047 | dev_err(hsotg->dev, | ||
1048 | "Unable to clear enable on channel %d\n", | ||
1049 | i); | ||
1050 | break; | ||
1051 | } | ||
1052 | udelay(1); | ||
1053 | } while (hcchar & HCCHAR_CHENA); | ||
1054 | } | ||
1055 | } | ||
1056 | |||
1057 | /* Turn on the vbus power */ | ||
1058 | dev_dbg(hsotg->dev, "Init: Port Power? op_state=%d\n", hsotg->op_state); | ||
1059 | if (hsotg->op_state == OTG_STATE_A_HOST) { | ||
1060 | u32 hprt0 = dwc2_read_hprt0(hsotg); | ||
1061 | |||
1062 | dev_dbg(hsotg->dev, "Init: Power Port (%d)\n", | ||
1063 | !!(hprt0 & HPRT0_PWR)); | ||
1064 | if (!(hprt0 & HPRT0_PWR)) { | ||
1065 | hprt0 |= HPRT0_PWR; | ||
1066 | dwc2_writel(hprt0, hsotg->regs + HPRT0); | ||
1067 | } | ||
1068 | } | ||
1069 | |||
1070 | dwc2_enable_host_interrupts(hsotg); | ||
1071 | } | ||
1072 | |||
1073 | static void dwc2_hc_enable_slave_ints(struct dwc2_hsotg *hsotg, | ||
1074 | struct dwc2_host_chan *chan) | ||
1075 | { | ||
1076 | u32 hcintmsk = HCINTMSK_CHHLTD; | ||
1077 | |||
1078 | switch (chan->ep_type) { | ||
1079 | case USB_ENDPOINT_XFER_CONTROL: | ||
1080 | case USB_ENDPOINT_XFER_BULK: | ||
1081 | dev_vdbg(hsotg->dev, "control/bulk\n"); | ||
1082 | hcintmsk |= HCINTMSK_XFERCOMPL; | ||
1083 | hcintmsk |= HCINTMSK_STALL; | ||
1084 | hcintmsk |= HCINTMSK_XACTERR; | ||
1085 | hcintmsk |= HCINTMSK_DATATGLERR; | ||
1086 | if (chan->ep_is_in) { | ||
1087 | hcintmsk |= HCINTMSK_BBLERR; | ||
1088 | } else { | ||
1089 | hcintmsk |= HCINTMSK_NAK; | ||
1090 | hcintmsk |= HCINTMSK_NYET; | ||
1091 | if (chan->do_ping) | ||
1092 | hcintmsk |= HCINTMSK_ACK; | ||
1093 | } | ||
1094 | |||
1095 | if (chan->do_split) { | ||
1096 | hcintmsk |= HCINTMSK_NAK; | ||
1097 | if (chan->complete_split) | ||
1098 | hcintmsk |= HCINTMSK_NYET; | ||
1099 | else | ||
1100 | hcintmsk |= HCINTMSK_ACK; | ||
1101 | } | ||
1102 | |||
1103 | if (chan->error_state) | ||
1104 | hcintmsk |= HCINTMSK_ACK; | ||
1105 | break; | ||
1106 | |||
1107 | case USB_ENDPOINT_XFER_INT: | ||
1108 | if (dbg_perio()) | ||
1109 | dev_vdbg(hsotg->dev, "intr\n"); | ||
1110 | hcintmsk |= HCINTMSK_XFERCOMPL; | ||
1111 | hcintmsk |= HCINTMSK_NAK; | ||
1112 | hcintmsk |= HCINTMSK_STALL; | ||
1113 | hcintmsk |= HCINTMSK_XACTERR; | ||
1114 | hcintmsk |= HCINTMSK_DATATGLERR; | ||
1115 | hcintmsk |= HCINTMSK_FRMOVRUN; | ||
1116 | |||
1117 | if (chan->ep_is_in) | ||
1118 | hcintmsk |= HCINTMSK_BBLERR; | ||
1119 | if (chan->error_state) | ||
1120 | hcintmsk |= HCINTMSK_ACK; | ||
1121 | if (chan->do_split) { | ||
1122 | if (chan->complete_split) | ||
1123 | hcintmsk |= HCINTMSK_NYET; | ||
1124 | else | ||
1125 | hcintmsk |= HCINTMSK_ACK; | ||
1126 | } | ||
1127 | break; | ||
1128 | |||
1129 | case USB_ENDPOINT_XFER_ISOC: | ||
1130 | if (dbg_perio()) | ||
1131 | dev_vdbg(hsotg->dev, "isoc\n"); | ||
1132 | hcintmsk |= HCINTMSK_XFERCOMPL; | ||
1133 | hcintmsk |= HCINTMSK_FRMOVRUN; | ||
1134 | hcintmsk |= HCINTMSK_ACK; | ||
1135 | |||
1136 | if (chan->ep_is_in) { | ||
1137 | hcintmsk |= HCINTMSK_XACTERR; | ||
1138 | hcintmsk |= HCINTMSK_BBLERR; | ||
1139 | } | ||
1140 | break; | ||
1141 | default: | ||
1142 | dev_err(hsotg->dev, "## Unknown EP type ##\n"); | ||
1143 | break; | ||
1144 | } | ||
1145 | |||
1146 | dwc2_writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num)); | ||
1147 | if (dbg_hc(chan)) | ||
1148 | dev_vdbg(hsotg->dev, "set HCINTMSK to %08x\n", hcintmsk); | ||
1149 | } | ||
1150 | |||
1151 | static void dwc2_hc_enable_dma_ints(struct dwc2_hsotg *hsotg, | ||
1152 | struct dwc2_host_chan *chan) | ||
1153 | { | ||
1154 | u32 hcintmsk = HCINTMSK_CHHLTD; | ||
1155 | |||
1156 | /* | ||
1157 | * For Descriptor DMA mode core halts the channel on AHB error. | ||
1158 | * Interrupt is not required. | ||
1159 | */ | ||
1160 | if (hsotg->core_params->dma_desc_enable <= 0) { | ||
1161 | if (dbg_hc(chan)) | ||
1162 | dev_vdbg(hsotg->dev, "desc DMA disabled\n"); | ||
1163 | hcintmsk |= HCINTMSK_AHBERR; | ||
1164 | } else { | ||
1165 | if (dbg_hc(chan)) | ||
1166 | dev_vdbg(hsotg->dev, "desc DMA enabled\n"); | ||
1167 | if (chan->ep_type == USB_ENDPOINT_XFER_ISOC) | ||
1168 | hcintmsk |= HCINTMSK_XFERCOMPL; | ||
1169 | } | ||
1170 | |||
1171 | if (chan->error_state && !chan->do_split && | ||
1172 | chan->ep_type != USB_ENDPOINT_XFER_ISOC) { | ||
1173 | if (dbg_hc(chan)) | ||
1174 | dev_vdbg(hsotg->dev, "setting ACK\n"); | ||
1175 | hcintmsk |= HCINTMSK_ACK; | ||
1176 | if (chan->ep_is_in) { | ||
1177 | hcintmsk |= HCINTMSK_DATATGLERR; | ||
1178 | if (chan->ep_type != USB_ENDPOINT_XFER_INT) | ||
1179 | hcintmsk |= HCINTMSK_NAK; | ||
1180 | } | ||
1181 | } | ||
1182 | |||
1183 | dwc2_writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num)); | ||
1184 | if (dbg_hc(chan)) | ||
1185 | dev_vdbg(hsotg->dev, "set HCINTMSK to %08x\n", hcintmsk); | ||
1186 | } | ||
1187 | |||
1188 | static void dwc2_hc_enable_ints(struct dwc2_hsotg *hsotg, | ||
1189 | struct dwc2_host_chan *chan) | ||
1190 | { | ||
1191 | u32 intmsk; | ||
1192 | |||
1193 | if (hsotg->core_params->dma_enable > 0) { | ||
1194 | if (dbg_hc(chan)) | ||
1195 | dev_vdbg(hsotg->dev, "DMA enabled\n"); | ||
1196 | dwc2_hc_enable_dma_ints(hsotg, chan); | ||
1197 | } else { | ||
1198 | if (dbg_hc(chan)) | ||
1199 | dev_vdbg(hsotg->dev, "DMA disabled\n"); | ||
1200 | dwc2_hc_enable_slave_ints(hsotg, chan); | ||
1201 | } | ||
1202 | |||
1203 | /* Enable the top level host channel interrupt */ | ||
1204 | intmsk = dwc2_readl(hsotg->regs + HAINTMSK); | ||
1205 | intmsk |= 1 << chan->hc_num; | ||
1206 | dwc2_writel(intmsk, hsotg->regs + HAINTMSK); | ||
1207 | if (dbg_hc(chan)) | ||
1208 | dev_vdbg(hsotg->dev, "set HAINTMSK to %08x\n", intmsk); | ||
1209 | |||
1210 | /* Make sure host channel interrupts are enabled */ | ||
1211 | intmsk = dwc2_readl(hsotg->regs + GINTMSK); | ||
1212 | intmsk |= GINTSTS_HCHINT; | ||
1213 | dwc2_writel(intmsk, hsotg->regs + GINTMSK); | ||
1214 | if (dbg_hc(chan)) | ||
1215 | dev_vdbg(hsotg->dev, "set GINTMSK to %08x\n", intmsk); | ||
1216 | } | ||
1217 | |||
1218 | /** | ||
1219 | * dwc2_hc_init() - Prepares a host channel for transferring packets to/from | ||
1220 | * a specific endpoint | ||
1221 | * | ||
1222 | * @hsotg: Programming view of DWC_otg controller | ||
1223 | * @chan: Information needed to initialize the host channel | ||
1224 | * | ||
1225 | * The HCCHARn register is set up with the characteristics specified in chan. | ||
1226 | * Host channel interrupts that may need to be serviced while this transfer is | ||
1227 | * in progress are enabled. | ||
1228 | */ | ||
1229 | void dwc2_hc_init(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan) | ||
1230 | { | ||
1231 | u8 hc_num = chan->hc_num; | ||
1232 | u32 hcintmsk; | ||
1233 | u32 hcchar; | ||
1234 | u32 hcsplt = 0; | ||
1235 | |||
1236 | if (dbg_hc(chan)) | ||
1237 | dev_vdbg(hsotg->dev, "%s()\n", __func__); | ||
1238 | |||
1239 | /* Clear old interrupt conditions for this host channel */ | ||
1240 | hcintmsk = 0xffffffff; | ||
1241 | hcintmsk &= ~HCINTMSK_RESERVED14_31; | ||
1242 | dwc2_writel(hcintmsk, hsotg->regs + HCINT(hc_num)); | ||
1243 | |||
1244 | /* Enable channel interrupts required for this transfer */ | ||
1245 | dwc2_hc_enable_ints(hsotg, chan); | ||
1246 | |||
1247 | /* | ||
1248 | * Program the HCCHARn register with the endpoint characteristics for | ||
1249 | * the current transfer | ||
1250 | */ | ||
1251 | hcchar = chan->dev_addr << HCCHAR_DEVADDR_SHIFT & HCCHAR_DEVADDR_MASK; | ||
1252 | hcchar |= chan->ep_num << HCCHAR_EPNUM_SHIFT & HCCHAR_EPNUM_MASK; | ||
1253 | if (chan->ep_is_in) | ||
1254 | hcchar |= HCCHAR_EPDIR; | ||
1255 | if (chan->speed == USB_SPEED_LOW) | ||
1256 | hcchar |= HCCHAR_LSPDDEV; | ||
1257 | hcchar |= chan->ep_type << HCCHAR_EPTYPE_SHIFT & HCCHAR_EPTYPE_MASK; | ||
1258 | hcchar |= chan->max_packet << HCCHAR_MPS_SHIFT & HCCHAR_MPS_MASK; | ||
1259 | dwc2_writel(hcchar, hsotg->regs + HCCHAR(hc_num)); | ||
1260 | if (dbg_hc(chan)) { | ||
1261 | dev_vdbg(hsotg->dev, "set HCCHAR(%d) to %08x\n", | ||
1262 | hc_num, hcchar); | ||
1263 | |||
1264 | dev_vdbg(hsotg->dev, "%s: Channel %d\n", | ||
1265 | __func__, hc_num); | ||
1266 | dev_vdbg(hsotg->dev, " Dev Addr: %d\n", | ||
1267 | chan->dev_addr); | ||
1268 | dev_vdbg(hsotg->dev, " Ep Num: %d\n", | ||
1269 | chan->ep_num); | ||
1270 | dev_vdbg(hsotg->dev, " Is In: %d\n", | ||
1271 | chan->ep_is_in); | ||
1272 | dev_vdbg(hsotg->dev, " Is Low Speed: %d\n", | ||
1273 | chan->speed == USB_SPEED_LOW); | ||
1274 | dev_vdbg(hsotg->dev, " Ep Type: %d\n", | ||
1275 | chan->ep_type); | ||
1276 | dev_vdbg(hsotg->dev, " Max Pkt: %d\n", | ||
1277 | chan->max_packet); | ||
1278 | } | ||
1279 | |||
1280 | /* Program the HCSPLT register for SPLITs */ | ||
1281 | if (chan->do_split) { | ||
1282 | if (dbg_hc(chan)) | ||
1283 | dev_vdbg(hsotg->dev, | ||
1284 | "Programming HC %d with split --> %s\n", | ||
1285 | hc_num, | ||
1286 | chan->complete_split ? "CSPLIT" : "SSPLIT"); | ||
1287 | if (chan->complete_split) | ||
1288 | hcsplt |= HCSPLT_COMPSPLT; | ||
1289 | hcsplt |= chan->xact_pos << HCSPLT_XACTPOS_SHIFT & | ||
1290 | HCSPLT_XACTPOS_MASK; | ||
1291 | hcsplt |= chan->hub_addr << HCSPLT_HUBADDR_SHIFT & | ||
1292 | HCSPLT_HUBADDR_MASK; | ||
1293 | hcsplt |= chan->hub_port << HCSPLT_PRTADDR_SHIFT & | ||
1294 | HCSPLT_PRTADDR_MASK; | ||
1295 | if (dbg_hc(chan)) { | ||
1296 | dev_vdbg(hsotg->dev, " comp split %d\n", | ||
1297 | chan->complete_split); | ||
1298 | dev_vdbg(hsotg->dev, " xact pos %d\n", | ||
1299 | chan->xact_pos); | ||
1300 | dev_vdbg(hsotg->dev, " hub addr %d\n", | ||
1301 | chan->hub_addr); | ||
1302 | dev_vdbg(hsotg->dev, " hub port %d\n", | ||
1303 | chan->hub_port); | ||
1304 | dev_vdbg(hsotg->dev, " is_in %d\n", | ||
1305 | chan->ep_is_in); | ||
1306 | dev_vdbg(hsotg->dev, " Max Pkt %d\n", | ||
1307 | chan->max_packet); | ||
1308 | dev_vdbg(hsotg->dev, " xferlen %d\n", | ||
1309 | chan->xfer_len); | ||
1310 | } | ||
1311 | } | ||
1312 | |||
1313 | dwc2_writel(hcsplt, hsotg->regs + HCSPLT(hc_num)); | ||
1314 | } | ||
1315 | |||
1316 | /** | ||
1317 | * dwc2_hc_halt() - Attempts to halt a host channel | ||
1318 | * | ||
1319 | * @hsotg: Controller register interface | ||
1320 | * @chan: Host channel to halt | ||
1321 | * @halt_status: Reason for halting the channel | ||
1322 | * | ||
1323 | * This function should only be called in Slave mode or to abort a transfer in | ||
1324 | * either Slave mode or DMA mode. Under normal circumstances in DMA mode, the | ||
1325 | * controller halts the channel when the transfer is complete or a condition | ||
1326 | * occurs that requires application intervention. | ||
1327 | * | ||
1328 | * In slave mode, checks for a free request queue entry, then sets the Channel | ||
1329 | * Enable and Channel Disable bits of the Host Channel Characteristics | ||
1330 | * register of the specified channel to intiate the halt. If there is no free | ||
1331 | * request queue entry, sets only the Channel Disable bit of the HCCHARn | ||
1332 | * register to flush requests for this channel. In the latter case, sets a | ||
1333 | * flag to indicate that the host channel needs to be halted when a request | ||
1334 | * queue slot is open. | ||
1335 | * | ||
1336 | * In DMA mode, always sets the Channel Enable and Channel Disable bits of the | ||
1337 | * HCCHARn register. The controller ensures there is space in the request | ||
1338 | * queue before submitting the halt request. | ||
1339 | * | ||
1340 | * Some time may elapse before the core flushes any posted requests for this | ||
1341 | * host channel and halts. The Channel Halted interrupt handler completes the | ||
1342 | * deactivation of the host channel. | ||
1343 | */ | ||
1344 | void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan, | ||
1345 | enum dwc2_halt_status halt_status) | ||
1346 | { | ||
1347 | u32 nptxsts, hptxsts, hcchar; | ||
1348 | |||
1349 | if (dbg_hc(chan)) | ||
1350 | dev_vdbg(hsotg->dev, "%s()\n", __func__); | ||
1351 | if (halt_status == DWC2_HC_XFER_NO_HALT_STATUS) | ||
1352 | dev_err(hsotg->dev, "!!! halt_status = %d !!!\n", halt_status); | ||
1353 | |||
1354 | if (halt_status == DWC2_HC_XFER_URB_DEQUEUE || | ||
1355 | halt_status == DWC2_HC_XFER_AHB_ERR) { | ||
1356 | /* | ||
1357 | * Disable all channel interrupts except Ch Halted. The QTD | ||
1358 | * and QH state associated with this transfer has been cleared | ||
1359 | * (in the case of URB_DEQUEUE), so the channel needs to be | ||
1360 | * shut down carefully to prevent crashes. | ||
1361 | */ | ||
1362 | u32 hcintmsk = HCINTMSK_CHHLTD; | ||
1363 | |||
1364 | dev_vdbg(hsotg->dev, "dequeue/error\n"); | ||
1365 | dwc2_writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num)); | ||
1366 | |||
1367 | /* | ||
1368 | * Make sure no other interrupts besides halt are currently | ||
1369 | * pending. Handling another interrupt could cause a crash due | ||
1370 | * to the QTD and QH state. | ||
1371 | */ | ||
1372 | dwc2_writel(~hcintmsk, hsotg->regs + HCINT(chan->hc_num)); | ||
1373 | |||
1374 | /* | ||
1375 | * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR | ||
1376 | * even if the channel was already halted for some other | ||
1377 | * reason | ||
1378 | */ | ||
1379 | chan->halt_status = halt_status; | ||
1380 | |||
1381 | hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num)); | ||
1382 | if (!(hcchar & HCCHAR_CHENA)) { | ||
1383 | /* | ||
1384 | * The channel is either already halted or it hasn't | ||
1385 | * started yet. In DMA mode, the transfer may halt if | ||
1386 | * it finishes normally or a condition occurs that | ||
1387 | * requires driver intervention. Don't want to halt | ||
1388 | * the channel again. In either Slave or DMA mode, | ||
1389 | * it's possible that the transfer has been assigned | ||
1390 | * to a channel, but not started yet when an URB is | ||
1391 | * dequeued. Don't want to halt a channel that hasn't | ||
1392 | * started yet. | ||
1393 | */ | ||
1394 | return; | ||
1395 | } | ||
1396 | } | ||
1397 | if (chan->halt_pending) { | ||
1398 | /* | ||
1399 | * A halt has already been issued for this channel. This might | ||
1400 | * happen when a transfer is aborted by a higher level in | ||
1401 | * the stack. | ||
1402 | */ | ||
1403 | dev_vdbg(hsotg->dev, | ||
1404 | "*** %s: Channel %d, chan->halt_pending already set ***\n", | ||
1405 | __func__, chan->hc_num); | ||
1406 | return; | ||
1407 | } | ||
1408 | |||
1409 | hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num)); | ||
1410 | |||
1411 | /* No need to set the bit in DDMA for disabling the channel */ | ||
1412 | /* TODO check it everywhere channel is disabled */ | ||
1413 | if (hsotg->core_params->dma_desc_enable <= 0) { | ||
1414 | if (dbg_hc(chan)) | ||
1415 | dev_vdbg(hsotg->dev, "desc DMA disabled\n"); | ||
1416 | hcchar |= HCCHAR_CHENA; | ||
1417 | } else { | ||
1418 | if (dbg_hc(chan)) | ||
1419 | dev_dbg(hsotg->dev, "desc DMA enabled\n"); | ||
1420 | } | ||
1421 | hcchar |= HCCHAR_CHDIS; | ||
1422 | |||
1423 | if (hsotg->core_params->dma_enable <= 0) { | ||
1424 | if (dbg_hc(chan)) | ||
1425 | dev_vdbg(hsotg->dev, "DMA not enabled\n"); | ||
1426 | hcchar |= HCCHAR_CHENA; | ||
1427 | |||
1428 | /* Check for space in the request queue to issue the halt */ | ||
1429 | if (chan->ep_type == USB_ENDPOINT_XFER_CONTROL || | ||
1430 | chan->ep_type == USB_ENDPOINT_XFER_BULK) { | ||
1431 | dev_vdbg(hsotg->dev, "control/bulk\n"); | ||
1432 | nptxsts = dwc2_readl(hsotg->regs + GNPTXSTS); | ||
1433 | if ((nptxsts & TXSTS_QSPCAVAIL_MASK) == 0) { | ||
1434 | dev_vdbg(hsotg->dev, "Disabling channel\n"); | ||
1435 | hcchar &= ~HCCHAR_CHENA; | ||
1436 | } | ||
1437 | } else { | ||
1438 | if (dbg_perio()) | ||
1439 | dev_vdbg(hsotg->dev, "isoc/intr\n"); | ||
1440 | hptxsts = dwc2_readl(hsotg->regs + HPTXSTS); | ||
1441 | if ((hptxsts & TXSTS_QSPCAVAIL_MASK) == 0 || | ||
1442 | hsotg->queuing_high_bandwidth) { | ||
1443 | if (dbg_perio()) | ||
1444 | dev_vdbg(hsotg->dev, "Disabling channel\n"); | ||
1445 | hcchar &= ~HCCHAR_CHENA; | ||
1446 | } | ||
1447 | } | ||
1448 | } else { | ||
1449 | if (dbg_hc(chan)) | ||
1450 | dev_vdbg(hsotg->dev, "DMA enabled\n"); | ||
1451 | } | ||
1452 | |||
1453 | dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); | ||
1454 | chan->halt_status = halt_status; | ||
1455 | |||
1456 | if (hcchar & HCCHAR_CHENA) { | ||
1457 | if (dbg_hc(chan)) | ||
1458 | dev_vdbg(hsotg->dev, "Channel enabled\n"); | ||
1459 | chan->halt_pending = 1; | ||
1460 | chan->halt_on_queue = 0; | ||
1461 | } else { | ||
1462 | if (dbg_hc(chan)) | ||
1463 | dev_vdbg(hsotg->dev, "Channel disabled\n"); | ||
1464 | chan->halt_on_queue = 1; | ||
1465 | } | ||
1466 | |||
1467 | if (dbg_hc(chan)) { | ||
1468 | dev_vdbg(hsotg->dev, "%s: Channel %d\n", __func__, | ||
1469 | chan->hc_num); | ||
1470 | dev_vdbg(hsotg->dev, " hcchar: 0x%08x\n", | ||
1471 | hcchar); | ||
1472 | dev_vdbg(hsotg->dev, " halt_pending: %d\n", | ||
1473 | chan->halt_pending); | ||
1474 | dev_vdbg(hsotg->dev, " halt_on_queue: %d\n", | ||
1475 | chan->halt_on_queue); | ||
1476 | dev_vdbg(hsotg->dev, " halt_status: %d\n", | ||
1477 | chan->halt_status); | ||
1478 | } | ||
1479 | } | ||
1480 | |||
1481 | /** | ||
1482 | * dwc2_hc_cleanup() - Clears the transfer state for a host channel | ||
1483 | * | ||
1484 | * @hsotg: Programming view of DWC_otg controller | ||
1485 | * @chan: Identifies the host channel to clean up | ||
1486 | * | ||
1487 | * This function is normally called after a transfer is done and the host | ||
1488 | * channel is being released | ||
1489 | */ | ||
1490 | void dwc2_hc_cleanup(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan) | ||
1491 | { | ||
1492 | u32 hcintmsk; | ||
1493 | |||
1494 | chan->xfer_started = 0; | ||
1495 | |||
1496 | list_del_init(&chan->split_order_list_entry); | ||
1497 | |||
1498 | /* | ||
1499 | * Clear channel interrupt enables and any unhandled channel interrupt | ||
1500 | * conditions | ||
1501 | */ | ||
1502 | dwc2_writel(0, hsotg->regs + HCINTMSK(chan->hc_num)); | ||
1503 | hcintmsk = 0xffffffff; | ||
1504 | hcintmsk &= ~HCINTMSK_RESERVED14_31; | ||
1505 | dwc2_writel(hcintmsk, hsotg->regs + HCINT(chan->hc_num)); | ||
1506 | } | ||
1507 | |||
1508 | /** | ||
1509 | * dwc2_hc_set_even_odd_frame() - Sets the channel property that indicates in | ||
1510 | * which frame a periodic transfer should occur | ||
1511 | * | ||
1512 | * @hsotg: Programming view of DWC_otg controller | ||
1513 | * @chan: Identifies the host channel to set up and its properties | ||
1514 | * @hcchar: Current value of the HCCHAR register for the specified host channel | ||
1515 | * | ||
1516 | * This function has no effect on non-periodic transfers | ||
1517 | */ | ||
1518 | static void dwc2_hc_set_even_odd_frame(struct dwc2_hsotg *hsotg, | ||
1519 | struct dwc2_host_chan *chan, u32 *hcchar) | ||
1520 | { | ||
1521 | if (chan->ep_type == USB_ENDPOINT_XFER_INT || | ||
1522 | chan->ep_type == USB_ENDPOINT_XFER_ISOC) { | ||
1523 | int host_speed; | ||
1524 | int xfer_ns; | ||
1525 | int xfer_us; | ||
1526 | int bytes_in_fifo; | ||
1527 | u16 fifo_space; | ||
1528 | u16 frame_number; | ||
1529 | u16 wire_frame; | ||
1530 | |||
1531 | /* | ||
1532 | * Try to figure out if we're an even or odd frame. If we set | ||
1533 | * even and the current frame number is even the the transfer | ||
1534 | * will happen immediately. Similar if both are odd. If one is | ||
1535 | * even and the other is odd then the transfer will happen when | ||
1536 | * the frame number ticks. | ||
1537 | * | ||
1538 | * There's a bit of a balancing act to get this right. | ||
1539 | * Sometimes we may want to send data in the current frame (AK | ||
1540 | * right away). We might want to do this if the frame number | ||
1541 | * _just_ ticked, but we might also want to do this in order | ||
1542 | * to continue a split transaction that happened late in a | ||
1543 | * microframe (so we didn't know to queue the next transfer | ||
1544 | * until the frame number had ticked). The problem is that we | ||
1545 | * need a lot of knowledge to know if there's actually still | ||
1546 | * time to send things or if it would be better to wait until | ||
1547 | * the next frame. | ||
1548 | * | ||
1549 | * We can look at how much time is left in the current frame | ||
1550 | * and make a guess about whether we'll have time to transfer. | ||
1551 | * We'll do that. | ||
1552 | */ | ||
1553 | |||
1554 | /* Get speed host is running at */ | ||
1555 | host_speed = (chan->speed != USB_SPEED_HIGH && | ||
1556 | !chan->do_split) ? chan->speed : USB_SPEED_HIGH; | ||
1557 | |||
1558 | /* See how many bytes are in the periodic FIFO right now */ | ||
1559 | fifo_space = (dwc2_readl(hsotg->regs + HPTXSTS) & | ||
1560 | TXSTS_FSPCAVAIL_MASK) >> TXSTS_FSPCAVAIL_SHIFT; | ||
1561 | bytes_in_fifo = sizeof(u32) * | ||
1562 | (hsotg->core_params->host_perio_tx_fifo_size - | ||
1563 | fifo_space); | ||
1564 | |||
1565 | /* | ||
1566 | * Roughly estimate bus time for everything in the periodic | ||
1567 | * queue + our new transfer. This is "rough" because we're | ||
1568 | * using a function that makes takes into account IN/OUT | ||
1569 | * and INT/ISO and we're just slamming in one value for all | ||
1570 | * transfers. This should be an over-estimate and that should | ||
1571 | * be OK, but we can probably tighten it. | ||
1572 | */ | ||
1573 | xfer_ns = usb_calc_bus_time(host_speed, false, false, | ||
1574 | chan->xfer_len + bytes_in_fifo); | ||
1575 | xfer_us = NS_TO_US(xfer_ns); | ||
1576 | |||
1577 | /* See what frame number we'll be at by the time we finish */ | ||
1578 | frame_number = dwc2_hcd_get_future_frame_number(hsotg, xfer_us); | ||
1579 | |||
1580 | /* This is when we were scheduled to be on the wire */ | ||
1581 | wire_frame = dwc2_frame_num_inc(chan->qh->next_active_frame, 1); | ||
1582 | |||
1583 | /* | ||
1584 | * If we'd finish _after_ the frame we're scheduled in then | ||
1585 | * it's hopeless. Just schedule right away and hope for the | ||
1586 | * best. Note that it _might_ be wise to call back into the | ||
1587 | * scheduler to pick a better frame, but this is better than | ||
1588 | * nothing. | ||
1589 | */ | ||
1590 | if (dwc2_frame_num_gt(frame_number, wire_frame)) { | ||
1591 | dwc2_sch_vdbg(hsotg, | ||
1592 | "QH=%p EO MISS fr=%04x=>%04x (%+d)\n", | ||
1593 | chan->qh, wire_frame, frame_number, | ||
1594 | dwc2_frame_num_dec(frame_number, | ||
1595 | wire_frame)); | ||
1596 | wire_frame = frame_number; | ||
1597 | |||
1598 | /* | ||
1599 | * We picked a different frame number; communicate this | ||
1600 | * back to the scheduler so it doesn't try to schedule | ||
1601 | * another in the same frame. | ||
1602 | * | ||
1603 | * Remember that next_active_frame is 1 before the wire | ||
1604 | * frame. | ||
1605 | */ | ||
1606 | chan->qh->next_active_frame = | ||
1607 | dwc2_frame_num_dec(frame_number, 1); | ||
1608 | } | ||
1609 | |||
1610 | if (wire_frame & 1) | ||
1611 | *hcchar |= HCCHAR_ODDFRM; | ||
1612 | else | ||
1613 | *hcchar &= ~HCCHAR_ODDFRM; | ||
1614 | } | ||
1615 | } | ||
1616 | |||
1617 | static void dwc2_set_pid_isoc(struct dwc2_host_chan *chan) | ||
1618 | { | ||
1619 | /* Set up the initial PID for the transfer */ | ||
1620 | if (chan->speed == USB_SPEED_HIGH) { | ||
1621 | if (chan->ep_is_in) { | ||
1622 | if (chan->multi_count == 1) | ||
1623 | chan->data_pid_start = DWC2_HC_PID_DATA0; | ||
1624 | else if (chan->multi_count == 2) | ||
1625 | chan->data_pid_start = DWC2_HC_PID_DATA1; | ||
1626 | else | ||
1627 | chan->data_pid_start = DWC2_HC_PID_DATA2; | ||
1628 | } else { | ||
1629 | if (chan->multi_count == 1) | ||
1630 | chan->data_pid_start = DWC2_HC_PID_DATA0; | ||
1631 | else | ||
1632 | chan->data_pid_start = DWC2_HC_PID_MDATA; | ||
1633 | } | ||
1634 | } else { | ||
1635 | chan->data_pid_start = DWC2_HC_PID_DATA0; | ||
1636 | } | ||
1637 | } | ||
1638 | |||
1639 | /** | ||
1640 | * dwc2_hc_write_packet() - Writes a packet into the Tx FIFO associated with | ||
1641 | * the Host Channel | ||
1642 | * | ||
1643 | * @hsotg: Programming view of DWC_otg controller | ||
1644 | * @chan: Information needed to initialize the host channel | ||
1645 | * | ||
1646 | * This function should only be called in Slave mode. For a channel associated | ||
1647 | * with a non-periodic EP, the non-periodic Tx FIFO is written. For a channel | ||
1648 | * associated with a periodic EP, the periodic Tx FIFO is written. | ||
1649 | * | ||
1650 | * Upon return the xfer_buf and xfer_count fields in chan are incremented by | ||
1651 | * the number of bytes written to the Tx FIFO. | ||
1652 | */ | ||
1653 | static void dwc2_hc_write_packet(struct dwc2_hsotg *hsotg, | ||
1654 | struct dwc2_host_chan *chan) | ||
1655 | { | ||
1656 | u32 i; | ||
1657 | u32 remaining_count; | ||
1658 | u32 byte_count; | ||
1659 | u32 dword_count; | ||
1660 | u32 __iomem *data_fifo; | ||
1661 | u32 *data_buf = (u32 *)chan->xfer_buf; | ||
1662 | |||
1663 | if (dbg_hc(chan)) | ||
1664 | dev_vdbg(hsotg->dev, "%s()\n", __func__); | ||
1665 | |||
1666 | data_fifo = (u32 __iomem *)(hsotg->regs + HCFIFO(chan->hc_num)); | ||
1667 | |||
1668 | remaining_count = chan->xfer_len - chan->xfer_count; | ||
1669 | if (remaining_count > chan->max_packet) | ||
1670 | byte_count = chan->max_packet; | ||
1671 | else | ||
1672 | byte_count = remaining_count; | ||
1673 | |||
1674 | dword_count = (byte_count + 3) / 4; | ||
1675 | |||
1676 | if (((unsigned long)data_buf & 0x3) == 0) { | ||
1677 | /* xfer_buf is DWORD aligned */ | ||
1678 | for (i = 0; i < dword_count; i++, data_buf++) | ||
1679 | dwc2_writel(*data_buf, data_fifo); | ||
1680 | } else { | ||
1681 | /* xfer_buf is not DWORD aligned */ | ||
1682 | for (i = 0; i < dword_count; i++, data_buf++) { | ||
1683 | u32 data = data_buf[0] | data_buf[1] << 8 | | ||
1684 | data_buf[2] << 16 | data_buf[3] << 24; | ||
1685 | dwc2_writel(data, data_fifo); | ||
1686 | } | ||
1687 | } | ||
1688 | |||
1689 | chan->xfer_count += byte_count; | ||
1690 | chan->xfer_buf += byte_count; | ||
1691 | } | ||
1692 | |||
1693 | /** | ||
1694 | * dwc2_hc_start_transfer() - Does the setup for a data transfer for a host | ||
1695 | * channel and starts the transfer | ||
1696 | * | ||
1697 | * @hsotg: Programming view of DWC_otg controller | ||
1698 | * @chan: Information needed to initialize the host channel. The xfer_len value | ||
1699 | * may be reduced to accommodate the max widths of the XferSize and | ||
1700 | * PktCnt fields in the HCTSIZn register. The multi_count value may be | ||
1701 | * changed to reflect the final xfer_len value. | ||
1702 | * | ||
1703 | * This function may be called in either Slave mode or DMA mode. In Slave mode, | ||
1704 | * the caller must ensure that there is sufficient space in the request queue | ||
1705 | * and Tx Data FIFO. | ||
1706 | * | ||
1707 | * For an OUT transfer in Slave mode, it loads a data packet into the | ||
1708 | * appropriate FIFO. If necessary, additional data packets are loaded in the | ||
1709 | * Host ISR. | ||
1710 | * | ||
1711 | * For an IN transfer in Slave mode, a data packet is requested. The data | ||
1712 | * packets are unloaded from the Rx FIFO in the Host ISR. If necessary, | ||
1713 | * additional data packets are requested in the Host ISR. | ||
1714 | * | ||
1715 | * For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ | ||
1716 | * register along with a packet count of 1 and the channel is enabled. This | ||
1717 | * causes a single PING transaction to occur. Other fields in HCTSIZ are | ||
1718 | * simply set to 0 since no data transfer occurs in this case. | ||
1719 | * | ||
1720 | * For a PING transfer in DMA mode, the HCTSIZ register is initialized with | ||
1721 | * all the information required to perform the subsequent data transfer. In | ||
1722 | * addition, the Do Ping bit is set in the HCTSIZ register. In this case, the | ||
1723 | * controller performs the entire PING protocol, then starts the data | ||
1724 | * transfer. | ||
1725 | */ | ||
1726 | void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg, | ||
1727 | struct dwc2_host_chan *chan) | ||
1728 | { | ||
1729 | u32 max_hc_xfer_size = hsotg->core_params->max_transfer_size; | ||
1730 | u16 max_hc_pkt_count = hsotg->core_params->max_packet_count; | ||
1731 | u32 hcchar; | ||
1732 | u32 hctsiz = 0; | ||
1733 | u16 num_packets; | ||
1734 | u32 ec_mc; | ||
1735 | |||
1736 | if (dbg_hc(chan)) | ||
1737 | dev_vdbg(hsotg->dev, "%s()\n", __func__); | ||
1738 | |||
1739 | if (chan->do_ping) { | ||
1740 | if (hsotg->core_params->dma_enable <= 0) { | ||
1741 | if (dbg_hc(chan)) | ||
1742 | dev_vdbg(hsotg->dev, "ping, no DMA\n"); | ||
1743 | dwc2_hc_do_ping(hsotg, chan); | ||
1744 | chan->xfer_started = 1; | ||
1745 | return; | ||
1746 | } else { | ||
1747 | if (dbg_hc(chan)) | ||
1748 | dev_vdbg(hsotg->dev, "ping, DMA\n"); | ||
1749 | hctsiz |= TSIZ_DOPNG; | ||
1750 | } | ||
1751 | } | ||
1752 | |||
1753 | if (chan->do_split) { | ||
1754 | if (dbg_hc(chan)) | ||
1755 | dev_vdbg(hsotg->dev, "split\n"); | ||
1756 | num_packets = 1; | ||
1757 | |||
1758 | if (chan->complete_split && !chan->ep_is_in) | ||
1759 | /* | ||
1760 | * For CSPLIT OUT Transfer, set the size to 0 so the | ||
1761 | * core doesn't expect any data written to the FIFO | ||
1762 | */ | ||
1763 | chan->xfer_len = 0; | ||
1764 | else if (chan->ep_is_in || chan->xfer_len > chan->max_packet) | ||
1765 | chan->xfer_len = chan->max_packet; | ||
1766 | else if (!chan->ep_is_in && chan->xfer_len > 188) | ||
1767 | chan->xfer_len = 188; | ||
1768 | |||
1769 | hctsiz |= chan->xfer_len << TSIZ_XFERSIZE_SHIFT & | ||
1770 | TSIZ_XFERSIZE_MASK; | ||
1771 | |||
1772 | /* For split set ec_mc for immediate retries */ | ||
1773 | if (chan->ep_type == USB_ENDPOINT_XFER_INT || | ||
1774 | chan->ep_type == USB_ENDPOINT_XFER_ISOC) | ||
1775 | ec_mc = 3; | ||
1776 | else | ||
1777 | ec_mc = 1; | ||
1778 | } else { | ||
1779 | if (dbg_hc(chan)) | ||
1780 | dev_vdbg(hsotg->dev, "no split\n"); | ||
1781 | /* | ||
1782 | * Ensure that the transfer length and packet count will fit | ||
1783 | * in the widths allocated for them in the HCTSIZn register | ||
1784 | */ | ||
1785 | if (chan->ep_type == USB_ENDPOINT_XFER_INT || | ||
1786 | chan->ep_type == USB_ENDPOINT_XFER_ISOC) { | ||
1787 | /* | ||
1788 | * Make sure the transfer size is no larger than one | ||
1789 | * (micro)frame's worth of data. (A check was done | ||
1790 | * when the periodic transfer was accepted to ensure | ||
1791 | * that a (micro)frame's worth of data can be | ||
1792 | * programmed into a channel.) | ||
1793 | */ | ||
1794 | u32 max_periodic_len = | ||
1795 | chan->multi_count * chan->max_packet; | ||
1796 | |||
1797 | if (chan->xfer_len > max_periodic_len) | ||
1798 | chan->xfer_len = max_periodic_len; | ||
1799 | } else if (chan->xfer_len > max_hc_xfer_size) { | ||
1800 | /* | ||
1801 | * Make sure that xfer_len is a multiple of max packet | ||
1802 | * size | ||
1803 | */ | ||
1804 | chan->xfer_len = | ||
1805 | max_hc_xfer_size - chan->max_packet + 1; | ||
1806 | } | ||
1807 | |||
1808 | if (chan->xfer_len > 0) { | ||
1809 | num_packets = (chan->xfer_len + chan->max_packet - 1) / | ||
1810 | chan->max_packet; | ||
1811 | if (num_packets > max_hc_pkt_count) { | ||
1812 | num_packets = max_hc_pkt_count; | ||
1813 | chan->xfer_len = num_packets * chan->max_packet; | ||
1814 | } | ||
1815 | } else { | ||
1816 | /* Need 1 packet for transfer length of 0 */ | ||
1817 | num_packets = 1; | ||
1818 | } | ||
1819 | |||
1820 | if (chan->ep_is_in) | ||
1821 | /* | ||
1822 | * Always program an integral # of max packets for IN | ||
1823 | * transfers | ||
1824 | */ | ||
1825 | chan->xfer_len = num_packets * chan->max_packet; | ||
1826 | |||
1827 | if (chan->ep_type == USB_ENDPOINT_XFER_INT || | ||
1828 | chan->ep_type == USB_ENDPOINT_XFER_ISOC) | ||
1829 | /* | ||
1830 | * Make sure that the multi_count field matches the | ||
1831 | * actual transfer length | ||
1832 | */ | ||
1833 | chan->multi_count = num_packets; | ||
1834 | |||
1835 | if (chan->ep_type == USB_ENDPOINT_XFER_ISOC) | ||
1836 | dwc2_set_pid_isoc(chan); | ||
1837 | |||
1838 | hctsiz |= chan->xfer_len << TSIZ_XFERSIZE_SHIFT & | ||
1839 | TSIZ_XFERSIZE_MASK; | ||
1840 | |||
1841 | /* The ec_mc gets the multi_count for non-split */ | ||
1842 | ec_mc = chan->multi_count; | ||
1843 | } | ||
1844 | |||
1845 | chan->start_pkt_count = num_packets; | ||
1846 | hctsiz |= num_packets << TSIZ_PKTCNT_SHIFT & TSIZ_PKTCNT_MASK; | ||
1847 | hctsiz |= chan->data_pid_start << TSIZ_SC_MC_PID_SHIFT & | ||
1848 | TSIZ_SC_MC_PID_MASK; | ||
1849 | dwc2_writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num)); | ||
1850 | if (dbg_hc(chan)) { | ||
1851 | dev_vdbg(hsotg->dev, "Wrote %08x to HCTSIZ(%d)\n", | ||
1852 | hctsiz, chan->hc_num); | ||
1853 | |||
1854 | dev_vdbg(hsotg->dev, "%s: Channel %d\n", __func__, | ||
1855 | chan->hc_num); | ||
1856 | dev_vdbg(hsotg->dev, " Xfer Size: %d\n", | ||
1857 | (hctsiz & TSIZ_XFERSIZE_MASK) >> | ||
1858 | TSIZ_XFERSIZE_SHIFT); | ||
1859 | dev_vdbg(hsotg->dev, " Num Pkts: %d\n", | ||
1860 | (hctsiz & TSIZ_PKTCNT_MASK) >> | ||
1861 | TSIZ_PKTCNT_SHIFT); | ||
1862 | dev_vdbg(hsotg->dev, " Start PID: %d\n", | ||
1863 | (hctsiz & TSIZ_SC_MC_PID_MASK) >> | ||
1864 | TSIZ_SC_MC_PID_SHIFT); | ||
1865 | } | ||
1866 | |||
1867 | if (hsotg->core_params->dma_enable > 0) { | ||
1868 | dwc2_writel((u32)chan->xfer_dma, | ||
1869 | hsotg->regs + HCDMA(chan->hc_num)); | ||
1870 | if (dbg_hc(chan)) | ||
1871 | dev_vdbg(hsotg->dev, "Wrote %08lx to HCDMA(%d)\n", | ||
1872 | (unsigned long)chan->xfer_dma, chan->hc_num); | ||
1873 | } | ||
1874 | |||
1875 | /* Start the split */ | ||
1876 | if (chan->do_split) { | ||
1877 | u32 hcsplt = dwc2_readl(hsotg->regs + HCSPLT(chan->hc_num)); | ||
1878 | |||
1879 | hcsplt |= HCSPLT_SPLTENA; | ||
1880 | dwc2_writel(hcsplt, hsotg->regs + HCSPLT(chan->hc_num)); | ||
1881 | } | ||
1882 | |||
1883 | hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num)); | ||
1884 | hcchar &= ~HCCHAR_MULTICNT_MASK; | ||
1885 | hcchar |= (ec_mc << HCCHAR_MULTICNT_SHIFT) & HCCHAR_MULTICNT_MASK; | ||
1886 | dwc2_hc_set_even_odd_frame(hsotg, chan, &hcchar); | ||
1887 | |||
1888 | if (hcchar & HCCHAR_CHDIS) | ||
1889 | dev_warn(hsotg->dev, | ||
1890 | "%s: chdis set, channel %d, hcchar 0x%08x\n", | ||
1891 | __func__, chan->hc_num, hcchar); | ||
1892 | |||
1893 | /* Set host channel enable after all other setup is complete */ | ||
1894 | hcchar |= HCCHAR_CHENA; | ||
1895 | hcchar &= ~HCCHAR_CHDIS; | ||
1896 | |||
1897 | if (dbg_hc(chan)) | ||
1898 | dev_vdbg(hsotg->dev, " Multi Cnt: %d\n", | ||
1899 | (hcchar & HCCHAR_MULTICNT_MASK) >> | ||
1900 | HCCHAR_MULTICNT_SHIFT); | ||
1901 | |||
1902 | dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); | ||
1903 | if (dbg_hc(chan)) | ||
1904 | dev_vdbg(hsotg->dev, "Wrote %08x to HCCHAR(%d)\n", hcchar, | ||
1905 | chan->hc_num); | ||
1906 | |||
1907 | chan->xfer_started = 1; | ||
1908 | chan->requests++; | ||
1909 | |||
1910 | if (hsotg->core_params->dma_enable <= 0 && | ||
1911 | !chan->ep_is_in && chan->xfer_len > 0) | ||
1912 | /* Load OUT packet into the appropriate Tx FIFO */ | ||
1913 | dwc2_hc_write_packet(hsotg, chan); | ||
1914 | } | ||
1915 | |||
1916 | /** | ||
1917 | * dwc2_hc_start_transfer_ddma() - Does the setup for a data transfer for a | ||
1918 | * host channel and starts the transfer in Descriptor DMA mode | ||
1919 | * | ||
1920 | * @hsotg: Programming view of DWC_otg controller | ||
1921 | * @chan: Information needed to initialize the host channel | ||
1922 | * | ||
1923 | * Initializes HCTSIZ register. For a PING transfer the Do Ping bit is set. | ||
1924 | * Sets PID and NTD values. For periodic transfers initializes SCHED_INFO field | ||
1925 | * with micro-frame bitmap. | ||
1926 | * | ||
1927 | * Initializes HCDMA register with descriptor list address and CTD value then | ||
1928 | * starts the transfer via enabling the channel. | ||
1929 | */ | ||
1930 | void dwc2_hc_start_transfer_ddma(struct dwc2_hsotg *hsotg, | ||
1931 | struct dwc2_host_chan *chan) | ||
1932 | { | ||
1933 | u32 hcchar; | ||
1934 | u32 hctsiz = 0; | ||
1935 | |||
1936 | if (chan->do_ping) | ||
1937 | hctsiz |= TSIZ_DOPNG; | ||
1938 | |||
1939 | if (chan->ep_type == USB_ENDPOINT_XFER_ISOC) | ||
1940 | dwc2_set_pid_isoc(chan); | ||
1941 | |||
1942 | /* Packet Count and Xfer Size are not used in Descriptor DMA mode */ | ||
1943 | hctsiz |= chan->data_pid_start << TSIZ_SC_MC_PID_SHIFT & | ||
1944 | TSIZ_SC_MC_PID_MASK; | ||
1945 | |||
1946 | /* 0 - 1 descriptor, 1 - 2 descriptors, etc */ | ||
1947 | hctsiz |= (chan->ntd - 1) << TSIZ_NTD_SHIFT & TSIZ_NTD_MASK; | ||
1948 | |||
1949 | /* Non-zero only for high-speed interrupt endpoints */ | ||
1950 | hctsiz |= chan->schinfo << TSIZ_SCHINFO_SHIFT & TSIZ_SCHINFO_MASK; | ||
1951 | |||
1952 | if (dbg_hc(chan)) { | ||
1953 | dev_vdbg(hsotg->dev, "%s: Channel %d\n", __func__, | ||
1954 | chan->hc_num); | ||
1955 | dev_vdbg(hsotg->dev, " Start PID: %d\n", | ||
1956 | chan->data_pid_start); | ||
1957 | dev_vdbg(hsotg->dev, " NTD: %d\n", chan->ntd - 1); | ||
1958 | } | ||
1959 | |||
1960 | dwc2_writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num)); | ||
1961 | |||
1962 | dma_sync_single_for_device(hsotg->dev, chan->desc_list_addr, | ||
1963 | chan->desc_list_sz, DMA_TO_DEVICE); | ||
1964 | |||
1965 | dwc2_writel(chan->desc_list_addr, hsotg->regs + HCDMA(chan->hc_num)); | ||
1966 | |||
1967 | if (dbg_hc(chan)) | ||
1968 | dev_vdbg(hsotg->dev, "Wrote %pad to HCDMA(%d)\n", | ||
1969 | &chan->desc_list_addr, chan->hc_num); | ||
1970 | |||
1971 | hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num)); | ||
1972 | hcchar &= ~HCCHAR_MULTICNT_MASK; | ||
1973 | hcchar |= chan->multi_count << HCCHAR_MULTICNT_SHIFT & | ||
1974 | HCCHAR_MULTICNT_MASK; | ||
1975 | |||
1976 | if (hcchar & HCCHAR_CHDIS) | ||
1977 | dev_warn(hsotg->dev, | ||
1978 | "%s: chdis set, channel %d, hcchar 0x%08x\n", | ||
1979 | __func__, chan->hc_num, hcchar); | ||
1980 | |||
1981 | /* Set host channel enable after all other setup is complete */ | ||
1982 | hcchar |= HCCHAR_CHENA; | ||
1983 | hcchar &= ~HCCHAR_CHDIS; | ||
1984 | |||
1985 | if (dbg_hc(chan)) | ||
1986 | dev_vdbg(hsotg->dev, " Multi Cnt: %d\n", | ||
1987 | (hcchar & HCCHAR_MULTICNT_MASK) >> | ||
1988 | HCCHAR_MULTICNT_SHIFT); | ||
1989 | |||
1990 | dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); | ||
1991 | if (dbg_hc(chan)) | ||
1992 | dev_vdbg(hsotg->dev, "Wrote %08x to HCCHAR(%d)\n", hcchar, | ||
1993 | chan->hc_num); | ||
1994 | |||
1995 | chan->xfer_started = 1; | ||
1996 | chan->requests++; | ||
1997 | } | ||
1998 | |||
1999 | /** | ||
2000 | * dwc2_hc_continue_transfer() - Continues a data transfer that was started by | ||
2001 | * a previous call to dwc2_hc_start_transfer() | ||
2002 | * | ||
2003 | * @hsotg: Programming view of DWC_otg controller | ||
2004 | * @chan: Information needed to initialize the host channel | ||
2005 | * | ||
2006 | * The caller must ensure there is sufficient space in the request queue and Tx | ||
2007 | * Data FIFO. This function should only be called in Slave mode. In DMA mode, | ||
2008 | * the controller acts autonomously to complete transfers programmed to a host | ||
2009 | * channel. | ||
2010 | * | ||
2011 | * For an OUT transfer, a new data packet is loaded into the appropriate FIFO | ||
2012 | * if there is any data remaining to be queued. For an IN transfer, another | ||
2013 | * data packet is always requested. For the SETUP phase of a control transfer, | ||
2014 | * this function does nothing. | ||
2015 | * | ||
2016 | * Return: 1 if a new request is queued, 0 if no more requests are required | ||
2017 | * for this transfer | ||
2018 | */ | ||
2019 | int dwc2_hc_continue_transfer(struct dwc2_hsotg *hsotg, | ||
2020 | struct dwc2_host_chan *chan) | ||
2021 | { | ||
2022 | if (dbg_hc(chan)) | ||
2023 | dev_vdbg(hsotg->dev, "%s: Channel %d\n", __func__, | ||
2024 | chan->hc_num); | ||
2025 | |||
2026 | if (chan->do_split) | ||
2027 | /* SPLITs always queue just once per channel */ | ||
2028 | return 0; | ||
2029 | |||
2030 | if (chan->data_pid_start == DWC2_HC_PID_SETUP) | ||
2031 | /* SETUPs are queued only once since they can't be NAK'd */ | ||
2032 | return 0; | ||
2033 | |||
2034 | if (chan->ep_is_in) { | ||
2035 | /* | ||
2036 | * Always queue another request for other IN transfers. If | ||
2037 | * back-to-back INs are issued and NAKs are received for both, | ||
2038 | * the driver may still be processing the first NAK when the | ||
2039 | * second NAK is received. When the interrupt handler clears | ||
2040 | * the NAK interrupt for the first NAK, the second NAK will | ||
2041 | * not be seen. So we can't depend on the NAK interrupt | ||
2042 | * handler to requeue a NAK'd request. Instead, IN requests | ||
2043 | * are issued each time this function is called. When the | ||
2044 | * transfer completes, the extra requests for the channel will | ||
2045 | * be flushed. | ||
2046 | */ | ||
2047 | u32 hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num)); | ||
2048 | |||
2049 | dwc2_hc_set_even_odd_frame(hsotg, chan, &hcchar); | ||
2050 | hcchar |= HCCHAR_CHENA; | ||
2051 | hcchar &= ~HCCHAR_CHDIS; | ||
2052 | if (dbg_hc(chan)) | ||
2053 | dev_vdbg(hsotg->dev, " IN xfer: hcchar = 0x%08x\n", | ||
2054 | hcchar); | ||
2055 | dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); | ||
2056 | chan->requests++; | ||
2057 | return 1; | ||
2058 | } | ||
2059 | |||
2060 | /* OUT transfers */ | ||
2061 | |||
2062 | if (chan->xfer_count < chan->xfer_len) { | ||
2063 | if (chan->ep_type == USB_ENDPOINT_XFER_INT || | ||
2064 | chan->ep_type == USB_ENDPOINT_XFER_ISOC) { | ||
2065 | u32 hcchar = dwc2_readl(hsotg->regs + | ||
2066 | HCCHAR(chan->hc_num)); | ||
2067 | |||
2068 | dwc2_hc_set_even_odd_frame(hsotg, chan, | ||
2069 | &hcchar); | ||
2070 | } | ||
2071 | |||
2072 | /* Load OUT packet into the appropriate Tx FIFO */ | ||
2073 | dwc2_hc_write_packet(hsotg, chan); | ||
2074 | chan->requests++; | ||
2075 | return 1; | ||
2076 | } | ||
2077 | |||
2078 | return 0; | ||
2079 | } | ||
2080 | |||
2081 | /** | ||
2082 | * dwc2_hc_do_ping() - Starts a PING transfer | ||
2083 | * | ||
2084 | * @hsotg: Programming view of DWC_otg controller | ||
2085 | * @chan: Information needed to initialize the host channel | ||
2086 | * | ||
2087 | * This function should only be called in Slave mode. The Do Ping bit is set in | ||
2088 | * the HCTSIZ register, then the channel is enabled. | ||
2089 | */ | ||
2090 | void dwc2_hc_do_ping(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan) | ||
2091 | { | ||
2092 | u32 hcchar; | ||
2093 | u32 hctsiz; | ||
2094 | |||
2095 | if (dbg_hc(chan)) | ||
2096 | dev_vdbg(hsotg->dev, "%s: Channel %d\n", __func__, | ||
2097 | chan->hc_num); | ||
2098 | |||
2099 | |||
2100 | hctsiz = TSIZ_DOPNG; | ||
2101 | hctsiz |= 1 << TSIZ_PKTCNT_SHIFT; | ||
2102 | dwc2_writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num)); | ||
2103 | |||
2104 | hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num)); | ||
2105 | hcchar |= HCCHAR_CHENA; | ||
2106 | hcchar &= ~HCCHAR_CHDIS; | ||
2107 | dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); | ||
2108 | } | ||
2109 | |||
2110 | /** | ||
2111 | * dwc2_calc_frame_interval() - Calculates the correct frame Interval value for | ||
2112 | * the HFIR register according to PHY type and speed | ||
2113 | * | ||
2114 | * @hsotg: Programming view of DWC_otg controller | ||
2115 | * | ||
2116 | * NOTE: The caller can modify the value of the HFIR register only after the | ||
2117 | * Port Enable bit of the Host Port Control and Status register (HPRT.EnaPort) | ||
2118 | * has been set | ||
2119 | */ | ||
2120 | u32 dwc2_calc_frame_interval(struct dwc2_hsotg *hsotg) | ||
2121 | { | ||
2122 | u32 usbcfg; | ||
2123 | u32 hprt0; | ||
2124 | int clock = 60; /* default value */ | ||
2125 | |||
2126 | usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); | ||
2127 | hprt0 = dwc2_readl(hsotg->regs + HPRT0); | ||
2128 | |||
2129 | if (!(usbcfg & GUSBCFG_PHYSEL) && (usbcfg & GUSBCFG_ULPI_UTMI_SEL) && | ||
2130 | !(usbcfg & GUSBCFG_PHYIF16)) | ||
2131 | clock = 60; | ||
2132 | if ((usbcfg & GUSBCFG_PHYSEL) && hsotg->hw_params.fs_phy_type == | ||
2133 | GHWCFG2_FS_PHY_TYPE_SHARED_ULPI) | ||
2134 | clock = 48; | ||
2135 | if (!(usbcfg & GUSBCFG_PHY_LP_CLK_SEL) && !(usbcfg & GUSBCFG_PHYSEL) && | ||
2136 | !(usbcfg & GUSBCFG_ULPI_UTMI_SEL) && (usbcfg & GUSBCFG_PHYIF16)) | ||
2137 | clock = 30; | ||
2138 | if (!(usbcfg & GUSBCFG_PHY_LP_CLK_SEL) && !(usbcfg & GUSBCFG_PHYSEL) && | ||
2139 | !(usbcfg & GUSBCFG_ULPI_UTMI_SEL) && !(usbcfg & GUSBCFG_PHYIF16)) | ||
2140 | clock = 60; | ||
2141 | if ((usbcfg & GUSBCFG_PHY_LP_CLK_SEL) && !(usbcfg & GUSBCFG_PHYSEL) && | ||
2142 | !(usbcfg & GUSBCFG_ULPI_UTMI_SEL) && (usbcfg & GUSBCFG_PHYIF16)) | ||
2143 | clock = 48; | ||
2144 | if ((usbcfg & GUSBCFG_PHYSEL) && !(usbcfg & GUSBCFG_PHYIF16) && | ||
2145 | hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_SHARED_UTMI) | ||
2146 | clock = 48; | ||
2147 | if ((usbcfg & GUSBCFG_PHYSEL) && | ||
2148 | hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED) | ||
2149 | clock = 48; | ||
2150 | |||
2151 | if ((hprt0 & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT == HPRT0_SPD_HIGH_SPEED) | ||
2152 | /* High speed case */ | ||
2153 | return 125 * clock - 1; | ||
2154 | else | ||
2155 | /* FS/LS case */ | ||
2156 | return 1000 * clock - 1; | ||
2157 | } | ||
2158 | |||
2159 | /** | ||
2160 | * dwc2_read_packet() - Reads a packet from the Rx FIFO into the destination | ||
2161 | * buffer | ||
2162 | * | ||
2163 | * @core_if: Programming view of DWC_otg controller | ||
2164 | * @dest: Destination buffer for the packet | ||
2165 | * @bytes: Number of bytes to copy to the destination | ||
2166 | */ | ||
2167 | void dwc2_read_packet(struct dwc2_hsotg *hsotg, u8 *dest, u16 bytes) | ||
2168 | { | ||
2169 | u32 __iomem *fifo = hsotg->regs + HCFIFO(0); | ||
2170 | u32 *data_buf = (u32 *)dest; | ||
2171 | int word_count = (bytes + 3) / 4; | ||
2172 | int i; | ||
2173 | |||
2174 | /* | ||
2175 | * Todo: Account for the case where dest is not dword aligned. This | ||
2176 | * requires reading data from the FIFO into a u32 temp buffer, then | ||
2177 | * moving it into the data buffer. | ||
2178 | */ | ||
2179 | |||
2180 | dev_vdbg(hsotg->dev, "%s(%p,%p,%d)\n", __func__, hsotg, dest, bytes); | ||
2181 | |||
2182 | for (i = 0; i < word_count; i++, data_buf++) | ||
2183 | *data_buf = dwc2_readl(fifo); | ||
2184 | } | ||
2185 | |||
2186 | /** | 410 | /** |
2187 | * dwc2_dump_host_registers() - Prints the host registers | 411 | * dwc2_dump_host_registers() - Prints the host registers |
2188 | * | 412 | * |