usb: dwc3: Set SUSPENDENABLE soon after phy init

After phy initialization, some phy operations can only be executed while
in lower P states. Ensure GUSB3PIPECTL.SUSPENDENABLE and
GUSB2PHYCFG.SUSPHY are set soon after initialization to avoid blocking
phy ops.

Previously the SUSPENDENABLE bits are only set after the controller
initialization, which may not happen right away if there's no gadget
driver or xhci driver bound. Revise this to clear SUSPENDENABLE bits
only when there's mode switching (change in GCTL.PRTCAPDIR).

Fixes: 6d735722063a ("usb: dwc3: core: Prevent phy suspend during init")
Cc: stable <stable@kernel.org>
Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://lore.kernel.org/r/633aef0afee7d56d2316f7cc3e1b2a6d518a8cc9.1738280911.git.Thinh.Nguyen@synopsys.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by Thinh Nguyen and committed by Greg Kroah-Hartman cc5bfc4e 2b66ef84

+45 -30
+42 -27
drivers/usb/dwc3/core.c
··· 131 } 132 } 133 134 - void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode) 135 { 136 u32 reg; 137 138 reg = dwc3_readl(dwc->regs, DWC3_GCTL); 139 reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG)); 140 reg |= DWC3_GCTL_PRTCAPDIR(mode); 141 dwc3_writel(dwc->regs, DWC3_GCTL, reg); ··· 229 230 spin_lock_irqsave(&dwc->lock, flags); 231 232 - dwc3_set_prtcap(dwc, desired_dr_role); 233 234 spin_unlock_irqrestore(&dwc->lock, flags); 235 ··· 671 */ 672 reg &= ~DWC3_GUSB3PIPECTL_UX_EXIT_PX; 673 674 - /* 675 - * Above DWC_usb3.0 1.94a, it is recommended to set 676 - * DWC3_GUSB3PIPECTL_SUSPHY to '0' during coreConsultant configuration. 677 - * So default value will be '0' when the core is reset. Application 678 - * needs to set it to '1' after the core initialization is completed. 679 - * 680 - * Similarly for DRD controllers, GUSB3PIPECTL.SUSPENDENABLE must be 681 - * cleared after power-on reset, and it can be set after core 682 - * initialization. 683 - */ 684 reg &= ~DWC3_GUSB3PIPECTL_SUSPHY; 685 686 if (dwc->u2ss_inp3_quirk) ··· 751 break; 752 } 753 754 - /* 755 - * Above DWC_usb3.0 1.94a, it is recommended to set 756 - * DWC3_GUSB2PHYCFG_SUSPHY to '0' during coreConsultant configuration. 757 - * So default value will be '0' when the core is reset. Application 758 - * needs to set it to '1' after the core initialization is completed. 759 - * 760 - * Similarly for DRD controllers, GUSB2PHYCFG.SUSPHY must be cleared 761 - * after power-on reset, and it can be set after core initialization. 762 - */ 763 reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; 764 765 if (dwc->dis_enblslpm_quirk) ··· 825 if (ret < 0) 826 goto err_exit_usb3_phy; 827 } 828 829 return 0; 830 ··· 1603 1604 switch (dwc->dr_mode) { 1605 case USB_DR_MODE_PERIPHERAL: 1606 - dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE); 1607 1608 if (dwc->usb2_phy) 1609 otg_set_vbus(dwc->usb2_phy->otg, false); ··· 1615 return dev_err_probe(dev, ret, "failed to initialize gadget\n"); 1616 break; 1617 case USB_DR_MODE_HOST: 1618 - dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST); 1619 1620 if (dwc->usb2_phy) 1621 otg_set_vbus(dwc->usb2_phy->otg, true); ··· 1660 } 1661 1662 /* de-assert DRVVBUS for HOST and OTG mode */ 1663 - dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE); 1664 } 1665 1666 static void dwc3_get_software_properties(struct dwc3 *dwc) ··· 2468 if (ret) 2469 return ret; 2470 2471 - dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE); 2472 dwc3_gadget_resume(dwc); 2473 break; 2474 case DWC3_GCTL_PRTCAP_HOST: ··· 2476 ret = dwc3_core_init_for_resume(dwc); 2477 if (ret) 2478 return ret; 2479 - dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST); 2480 break; 2481 } 2482 /* Restore GUSB2PHYCFG bits that were modified in suspend */ ··· 2505 if (ret) 2506 return ret; 2507 2508 - dwc3_set_prtcap(dwc, dwc->current_dr_role); 2509 2510 dwc3_otg_init(dwc); 2511 if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST) {
··· 131 } 132 } 133 134 + void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode, bool ignore_susphy) 135 { 136 + unsigned int hw_mode; 137 u32 reg; 138 139 reg = dwc3_readl(dwc->regs, DWC3_GCTL); 140 + 141 + /* 142 + * For DRD controllers, GUSB3PIPECTL.SUSPENDENABLE and 143 + * GUSB2PHYCFG.SUSPHY should be cleared during mode switching, 144 + * and they can be set after core initialization. 145 + */ 146 + hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0); 147 + if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD && !ignore_susphy) { 148 + if (DWC3_GCTL_PRTCAP(reg) != mode) 149 + dwc3_enable_susphy(dwc, false); 150 + } 151 + 152 reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG)); 153 reg |= DWC3_GCTL_PRTCAPDIR(mode); 154 dwc3_writel(dwc->regs, DWC3_GCTL, reg); ··· 216 217 spin_lock_irqsave(&dwc->lock, flags); 218 219 + dwc3_set_prtcap(dwc, desired_dr_role, false); 220 221 spin_unlock_irqrestore(&dwc->lock, flags); 222 ··· 658 */ 659 reg &= ~DWC3_GUSB3PIPECTL_UX_EXIT_PX; 660 661 + /* Ensure the GUSB3PIPECTL.SUSPENDENABLE is cleared prior to phy init. */ 662 reg &= ~DWC3_GUSB3PIPECTL_SUSPHY; 663 664 if (dwc->u2ss_inp3_quirk) ··· 747 break; 748 } 749 750 + /* Ensure the GUSB2PHYCFG.SUSPHY is cleared prior to phy init. */ 751 reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; 752 753 if (dwc->dis_enblslpm_quirk) ··· 829 if (ret < 0) 830 goto err_exit_usb3_phy; 831 } 832 + 833 + /* 834 + * Above DWC_usb3.0 1.94a, it is recommended to set 835 + * DWC3_GUSB3PIPECTL_SUSPHY and DWC3_GUSB2PHYCFG_SUSPHY to '0' during 836 + * coreConsultant configuration. So default value will be '0' when the 837 + * core is reset. Application needs to set it to '1' after the core 838 + * initialization is completed. 839 + * 840 + * Certain phy requires to be in P0 power state during initialization. 841 + * Make sure GUSB3PIPECTL.SUSPENDENABLE and GUSB2PHYCFG.SUSPHY are clear 842 + * prior to phy init to maintain in the P0 state. 843 + * 844 + * After phy initialization, some phy operations can only be executed 845 + * while in lower P states. Ensure GUSB3PIPECTL.SUSPENDENABLE and 846 + * GUSB2PHYCFG.SUSPHY are set soon after initialization to avoid 847 + * blocking phy ops. 848 + */ 849 + if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A)) 850 + dwc3_enable_susphy(dwc, true); 851 852 return 0; 853 ··· 1588 1589 switch (dwc->dr_mode) { 1590 case USB_DR_MODE_PERIPHERAL: 1591 + dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE, false); 1592 1593 if (dwc->usb2_phy) 1594 otg_set_vbus(dwc->usb2_phy->otg, false); ··· 1600 return dev_err_probe(dev, ret, "failed to initialize gadget\n"); 1601 break; 1602 case USB_DR_MODE_HOST: 1603 + dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST, false); 1604 1605 if (dwc->usb2_phy) 1606 otg_set_vbus(dwc->usb2_phy->otg, true); ··· 1645 } 1646 1647 /* de-assert DRVVBUS for HOST and OTG mode */ 1648 + dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE, true); 1649 } 1650 1651 static void dwc3_get_software_properties(struct dwc3 *dwc) ··· 2453 if (ret) 2454 return ret; 2455 2456 + dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE, true); 2457 dwc3_gadget_resume(dwc); 2458 break; 2459 case DWC3_GCTL_PRTCAP_HOST: ··· 2461 ret = dwc3_core_init_for_resume(dwc); 2462 if (ret) 2463 return ret; 2464 + dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST, true); 2465 break; 2466 } 2467 /* Restore GUSB2PHYCFG bits that were modified in suspend */ ··· 2490 if (ret) 2491 return ret; 2492 2493 + dwc3_set_prtcap(dwc, dwc->current_dr_role, true); 2494 2495 dwc3_otg_init(dwc); 2496 if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST) {
+1 -1
drivers/usb/dwc3/core.h
··· 1558 #define DWC3_HAS_OTG BIT(3) 1559 1560 /* prototypes */ 1561 - void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode); 1562 void dwc3_set_mode(struct dwc3 *dwc, u32 mode); 1563 u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type); 1564
··· 1558 #define DWC3_HAS_OTG BIT(3) 1559 1560 /* prototypes */ 1561 + void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode, bool ignore_susphy); 1562 void dwc3_set_mode(struct dwc3 *dwc, u32 mode); 1563 u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type); 1564
+2 -2
drivers/usb/dwc3/drd.c
··· 173 * block "Initialize GCTL for OTG operation". 174 */ 175 /* GCTL.PrtCapDir=2'b11 */ 176 - dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_OTG); 177 /* GUSB2PHYCFG0.SusPHY=0 */ 178 reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); 179 reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; ··· 556 557 dwc3_drd_update(dwc); 558 } else { 559 - dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_OTG); 560 561 /* use OTG block to get ID event */ 562 irq = dwc3_otg_get_irq(dwc);
··· 173 * block "Initialize GCTL for OTG operation". 174 */ 175 /* GCTL.PrtCapDir=2'b11 */ 176 + dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_OTG, true); 177 /* GUSB2PHYCFG0.SusPHY=0 */ 178 reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); 179 reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; ··· 556 557 dwc3_drd_update(dwc); 558 } else { 559 + dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_OTG, true); 560 561 /* use OTG block to get ID event */ 562 irq = dwc3_otg_get_irq(dwc);