Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

phy: fsl-imx8mq-usb: enable RX Termination override

This is to resolve the problem of wakeup system by USB3 device insertion
if HSIOMIX on, in that case, the USB3 device detects RX term on so the
USB3 device doesn't downgrade to high-speed, we can't expect CONN wakeup
(for USB3) happen because the 24MHz OSC is required ON to trigger it.
Because the device works at Super-speed so DP/DM wakeup can't happen
either. Then the entire systen can't be waken up by such device attach
event.

With this override bit we can force the RX term off when enters system
suspend, and disable the override after system resume. Therefore, the
USB3 device will always downgrade to High-speed, then DP/DM wakeup can
always happen. It will correctly switch to Super-speed later when the
host reset it after the system resume back.

Signed-off-by: Li Jun <jun.li@nxp.com>
Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
Link: https://patch.msgid.link/20260116101835.1810675-1-xu.yang_2@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Xu Yang and committed by
Vinod Koul
05b56ef3 debf8326

+14 -1
+14 -1
drivers/phy/freescale/phy-fsl-imx8mq-usb.c
··· 51 51 #define PHY_CTRL5_PCS_TX_SWING_FULL_MASK GENMASK(6, 0) 52 52 53 53 #define PHY_CTRL6 0x18 54 + #define PHY_CTRL6_RXTERM_OVERRIDE_SEL BIT(29) 54 55 #define PHY_CTRL6_ALT_CLK_EN BIT(1) 55 56 #define PHY_CTRL6_ALT_CLK_SEL BIT(0) 56 57 ··· 631 630 static int imx8mq_phy_power_on(struct phy *phy) 632 631 { 633 632 struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy); 633 + u32 value; 634 634 int ret; 635 635 636 636 ret = regulator_enable(imx_phy->vbus); ··· 648 646 return ret; 649 647 } 650 648 651 - return ret; 649 + /* Disable rx term override */ 650 + value = readl(imx_phy->base + PHY_CTRL6); 651 + value &= ~PHY_CTRL6_RXTERM_OVERRIDE_SEL; 652 + writel(value, imx_phy->base + PHY_CTRL6); 653 + 654 + return 0; 652 655 } 653 656 654 657 static int imx8mq_phy_power_off(struct phy *phy) 655 658 { 656 659 struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy); 660 + u32 value; 661 + 662 + /* Override rx term to be 0 */ 663 + value = readl(imx_phy->base + PHY_CTRL6); 664 + value |= PHY_CTRL6_RXTERM_OVERRIDE_SEL; 665 + writel(value, imx_phy->base + PHY_CTRL6); 657 666 658 667 clk_disable_unprepare(imx_phy->alt_clk); 659 668 clk_disable_unprepare(imx_phy->clk);