From 070d546258257c75c65a2f15da558eb96bce550c Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Mon, 7 Apr 2025 11:56:06 -0500 Subject: [PATCH 01/16] dt-bindings: phy: rockchip: Add missing "phy-supply" property Several Rockchip PHYs use the "phy-supply" property, but don't document it. Add it to the current known users. Signed-off-by: Rob Herring (Arm) Reviewed-by: Heiko Stuebner Link: https://lore.kernel.org/r/20250407165607.2937088-1-robh@kernel.org Signed-off-by: Vinod Koul --- .../devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml | 3 +++ Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml | 3 +++ Documentation/devicetree/bindings/phy/rockchip,pcie3-phy.yaml | 3 +++ 3 files changed, 9 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml index 888e6b2aac5a..3e101c3c5ea9 100644 --- a/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml +++ b/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml @@ -42,6 +42,9 @@ properties: - const: phy - const: apb + phy-supply: + description: Single PHY regulator + rockchip,enable-ssc: type: boolean description: diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml index b42f1272903d..8b7059d5b182 100644 --- a/Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml +++ b/Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml @@ -47,6 +47,9 @@ properties: - const: pcs_apb - const: pma_apb + phy-supply: + description: Single PHY regulator + rockchip,dp-lane-mux: $ref: /schemas/types.yaml#/definitions/uint32-array minItems: 2 diff --git a/Documentation/devicetree/bindings/phy/rockchip,pcie3-phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,pcie3-phy.yaml index ba67dca5a446..d7de8b527c5c 100644 --- a/Documentation/devicetree/bindings/phy/rockchip,pcie3-phy.yaml +++ b/Documentation/devicetree/bindings/phy/rockchip,pcie3-phy.yaml @@ -46,6 +46,9 @@ properties: reset-names: const: phy + phy-supply: + description: Single PHY regulator + rockchip,phy-grf: $ref: /schemas/types.yaml#/definitions/phandle description: phandle to the syscon managing the phy "general register files" -- 2.51.0 From 9b6662a0f715b3f43b42c3aadf32fa6ffaa8890c Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Thu, 10 Apr 2025 14:01:12 +0530 Subject: [PATCH 02/16] phy: exynos5-usbdrd: use GENMASK and FIELD_PREP for Exynos5 PHY registers Most Exynos850 and Exynos9 (GS101) DRD PHY registers use GENMASK for masks and FIELD_PREP for writing values to registers. Rewrite the register definitions which don't follow this approach to follow it as much as possible. This patch doesn't introduce any fixes or functional changes, it's merely an attempt to introduce some uniformity and consistency in the driver code. The CRPORT SuperSpeed control registers have been exempted from this change. Since the writing of register values do not require any masking operations, implementing it would unnecessarily complicate things. Signed-off-by: Kaustabh Chakraborty Link: https://lore.kernel.org/r/20250410-exynos7870-usbphy-v2-1-2eb005987455@disroot.org Signed-off-by: Vinod Koul --- drivers/phy/samsung/phy-exynos5-usbdrd.c | 147 ++++++++++++----------- 1 file changed, 75 insertions(+), 72 deletions(-) diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c index 817fddee0392..534ccea93795 100644 --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c @@ -39,8 +39,7 @@ /* Exynos5: USB 3.0 DRD PHY registers */ #define EXYNOS5_DRD_LINKSYSTEM 0x04 #define LINKSYSTEM_XHCI_VERSION_CONTROL BIT(27) -#define LINKSYSTEM_FLADJ_MASK (0x3f << 1) -#define LINKSYSTEM_FLADJ(_x) ((_x) << 1) +#define LINKSYSTEM_FLADJ GENMASK(6, 1) #define EXYNOS5_DRD_PHYUTMI 0x08 #define PHYUTMI_OTGDISABLE BIT(6) @@ -51,30 +50,27 @@ #define EXYNOS5_DRD_PHYCLKRST 0x10 #define PHYCLKRST_EN_UTMISUSPEND BIT(31) -#define PHYCLKRST_SSC_REFCLKSEL_MASK (0xff << 23) -#define PHYCLKRST_SSC_REFCLKSEL(_x) ((_x) << 23) -#define PHYCLKRST_SSC_RANGE_MASK (0x03 << 21) -#define PHYCLKRST_SSC_RANGE(_x) ((_x) << 21) +#define PHYCLKRST_SSC_REFCLKSEL GENMASK(30, 23) +#define PHYCLKRST_SSC_RANGE GENMASK(22, 21) #define PHYCLKRST_SSC_EN BIT(20) #define PHYCLKRST_REF_SSP_EN BIT(19) #define PHYCLKRST_REF_CLKDIV2 BIT(18) -#define PHYCLKRST_MPLL_MULTIPLIER_MASK (0x7f << 11) -#define PHYCLKRST_MPLL_MULTIPLIER_100MHZ_REF (0x19 << 11) -#define PHYCLKRST_MPLL_MULTIPLIER_50M_REF (0x32 << 11) -#define PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF (0x68 << 11) -#define PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF (0x7d << 11) -#define PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF (0x02 << 11) -#define PHYCLKRST_FSEL_PIPE_MASK (0x7 << 8) -#define PHYCLKRST_FSEL_UTMI_MASK (0x7 << 5) -#define PHYCLKRST_FSEL(_x) ((_x) << 5) -#define PHYCLKRST_FSEL_PAD_100MHZ (0x27 << 5) -#define PHYCLKRST_FSEL_PAD_24MHZ (0x2a << 5) -#define PHYCLKRST_FSEL_PAD_20MHZ (0x31 << 5) -#define PHYCLKRST_FSEL_PAD_19_2MHZ (0x38 << 5) +#define PHYCLKRST_MPLL_MULTIPLIER GENMASK(17, 11) +#define PHYCLKRST_MPLL_MULTIPLIER_100MHZ_REF 0x19 +#define PHYCLKRST_MPLL_MULTIPLIER_50M_REF 0x32 +#define PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF 0x68 +#define PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF 0x7d +#define PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF 0x02 +#define PHYCLKRST_FSEL_PIPE GENMASK(10, 8) +#define PHYCLKRST_FSEL_UTMI GENMASK(7, 5) +#define PHYCLKRST_FSEL_PAD_100MHZ 0x27 +#define PHYCLKRST_FSEL_PAD_24MHZ 0x2a +#define PHYCLKRST_FSEL_PAD_20MHZ 0x31 +#define PHYCLKRST_FSEL_PAD_19_2MHZ 0x38 #define PHYCLKRST_RETENABLEN BIT(4) -#define PHYCLKRST_REFCLKSEL_MASK (0x03 << 2) -#define PHYCLKRST_REFCLKSEL_PAD_REFCLK (0x2 << 2) -#define PHYCLKRST_REFCLKSEL_EXT_REFCLK (0x3 << 2) +#define PHYCLKRST_REFCLKSEL GENMASK(3, 2) +#define PHYCLKRST_REFCLKSEL_PAD_REFCLK 0x2 +#define PHYCLKRST_REFCLKSEL_EXT_REFCLK 0x3 #define PHYCLKRST_PORTRESET BIT(1) #define PHYCLKRST_COMMONONN BIT(0) @@ -83,22 +79,22 @@ #define PHYREG0_SSC_RANGE BIT(20) #define PHYREG0_CR_WRITE BIT(19) #define PHYREG0_CR_READ BIT(18) -#define PHYREG0_CR_DATA_IN(_x) ((_x) << 2) +#define PHYREG0_CR_DATA_IN GENMASK(17, 2) #define PHYREG0_CR_CAP_DATA BIT(1) #define PHYREG0_CR_CAP_ADDR BIT(0) #define EXYNOS5_DRD_PHYREG1 0x18 -#define PHYREG1_CR_DATA_OUT(_x) ((_x) << 1) +#define PHYREG0_CR_DATA_OUT GENMASK(16, 1) #define PHYREG1_CR_ACK BIT(0) #define EXYNOS5_DRD_PHYPARAM0 0x1c #define PHYPARAM0_REF_USE_PAD BIT(31) -#define PHYPARAM0_REF_LOSLEVEL_MASK (0x1f << 26) -#define PHYPARAM0_REF_LOSLEVEL (0x9 << 26) +#define PHYPARAM0_REF_LOSLEVEL GENMASK(30, 26) +#define PHYPARAM0_REF_LOSLEVEL_VAL 0x9 #define EXYNOS5_DRD_PHYPARAM1 0x20 -#define PHYPARAM1_PCS_TXDEEMPH_MASK (0x1f << 0) -#define PHYPARAM1_PCS_TXDEEMPH (0x1c) +#define PHYPARAM1_PCS_TXDEEMPH GENMASK(4, 0) +#define PHYPARAM1_PCS_TXDEEMPH_VAL 0x1c #define EXYNOS5_DRD_PHYTERM 0x24 @@ -140,7 +136,7 @@ #define LINKCTRL_FORCE_PHYSTATUS BIT(17) #define LINKCTRL_FORCE_PIPE_EN BIT(16) #define LINKCTRL_FORCE_QACT BIT(8) -#define LINKCTRL_BUS_FILTER_BYPASS(_x) ((_x) << 4) +#define LINKCTRL_BUS_FILTER_BYPASS GENMASK(7, 4) #define EXYNOS850_DRD_LINKPORT 0x08 #define LINKPORT_HOST_NUM_U3 GENMASK(19, 16) @@ -497,29 +493,34 @@ exynos5_usbdrd_pipe3_set_refclk(struct phy_usb_instance *inst) reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); /* Use EXTREFCLK as ref clock */ - reg &= ~PHYCLKRST_REFCLKSEL_MASK; - reg |= PHYCLKRST_REFCLKSEL_EXT_REFCLK; + reg &= ~PHYCLKRST_REFCLKSEL; + reg |= FIELD_PREP_CONST(PHYCLKRST_REFCLKSEL, + PHYCLKRST_REFCLKSEL_EXT_REFCLK); /* FSEL settings corresponding to reference clock */ - reg &= ~(PHYCLKRST_FSEL_PIPE_MASK | - PHYCLKRST_MPLL_MULTIPLIER_MASK | - PHYCLKRST_SSC_REFCLKSEL_MASK); + reg &= ~(PHYCLKRST_FSEL_PIPE | + PHYCLKRST_MPLL_MULTIPLIER | + PHYCLKRST_SSC_REFCLKSEL); switch (phy_drd->extrefclk) { case EXYNOS5_FSEL_50MHZ: - reg |= (PHYCLKRST_MPLL_MULTIPLIER_50M_REF | - PHYCLKRST_SSC_REFCLKSEL(0x00)); + reg |= (FIELD_PREP_CONST(PHYCLKRST_SSC_REFCLKSEL, 0x00) | + FIELD_PREP_CONST(PHYCLKRST_MPLL_MULTIPLIER, + PHYCLKRST_MPLL_MULTIPLIER_50M_REF)); break; case EXYNOS5_FSEL_24MHZ: - reg |= (PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF | - PHYCLKRST_SSC_REFCLKSEL(0x88)); + reg |= (FIELD_PREP_CONST(PHYCLKRST_SSC_REFCLKSEL, 0x88) | + FIELD_PREP_CONST(PHYCLKRST_MPLL_MULTIPLIER, + PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF)); break; case EXYNOS5_FSEL_20MHZ: - reg |= (PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF | - PHYCLKRST_SSC_REFCLKSEL(0x00)); + reg |= (FIELD_PREP_CONST(PHYCLKRST_SSC_REFCLKSEL, 0x00) | + FIELD_PREP_CONST(PHYCLKRST_MPLL_MULTIPLIER, + PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF)); break; case EXYNOS5_FSEL_19MHZ2: - reg |= (PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF | - PHYCLKRST_SSC_REFCLKSEL(0x88)); + reg |= (FIELD_PREP_CONST(PHYCLKRST_SSC_REFCLKSEL, 0x88) | + FIELD_PREP_CONST(PHYCLKRST_MPLL_MULTIPLIER, + PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF)); break; default: dev_dbg(phy_drd->dev, "unsupported ref clk\n"); @@ -542,13 +543,14 @@ exynos5_usbdrd_utmi_set_refclk(struct phy_usb_instance *inst) /* restore any previous reference clock settings */ reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); - reg &= ~PHYCLKRST_REFCLKSEL_MASK; - reg |= PHYCLKRST_REFCLKSEL_EXT_REFCLK; + reg &= ~PHYCLKRST_REFCLKSEL; + reg |= FIELD_PREP_CONST(PHYCLKRST_REFCLKSEL, + PHYCLKRST_REFCLKSEL_EXT_REFCLK); - reg &= ~(PHYCLKRST_FSEL_UTMI_MASK | - PHYCLKRST_MPLL_MULTIPLIER_MASK | - PHYCLKRST_SSC_REFCLKSEL_MASK); - reg |= PHYCLKRST_FSEL(phy_drd->extrefclk); + reg &= ~(PHYCLKRST_FSEL_UTMI | + PHYCLKRST_MPLL_MULTIPLIER | + PHYCLKRST_SSC_REFCLKSEL); + reg |= FIELD_PREP(PHYCLKRST_FSEL_UTMI, phy_drd->extrefclk); return reg; } @@ -598,8 +600,9 @@ static void exynos5_usbdrd_pipe3_init(struct exynos5_usbdrd_phy *phy_drd) reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); /* Set Tx De-Emphasis level */ - reg &= ~PHYPARAM1_PCS_TXDEEMPH_MASK; - reg |= PHYPARAM1_PCS_TXDEEMPH; + reg &= ~PHYPARAM1_PCS_TXDEEMPH; + reg |= FIELD_PREP_CONST(PHYPARAM1_PCS_TXDEEMPH, + PHYPARAM1_PCS_TXDEEMPH_VAL); writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYTEST); @@ -620,7 +623,7 @@ exynos5_usbdrd_usbdp_g2_v4_ctrl_pma_ready(struct exynos5_usbdrd_phy *phy_drd) reg = readl(regs_base + EXYNOS850_DRD_SECPMACTL); reg &= ~SECPMACTL_PMA_REF_FREQ_SEL; - reg |= FIELD_PREP(SECPMACTL_PMA_REF_FREQ_SEL, 1); + reg |= FIELD_PREP_CONST(SECPMACTL_PMA_REF_FREQ_SEL, 1); /* SFR reset */ reg |= (SECPMACTL_PMA_LOW_PWR | SECPMACTL_PMA_APB_SW_RST); reg &= ~(SECPMACTL_PMA_ROPLL_REF_CLK_SEL | @@ -749,14 +752,16 @@ static void exynos5_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM0); /* Set Loss-of-Signal Detector sensitivity */ - reg &= ~PHYPARAM0_REF_LOSLEVEL_MASK; - reg |= PHYPARAM0_REF_LOSLEVEL; + reg &= ~PHYPARAM0_REF_LOSLEVEL; + reg |= FIELD_PREP_CONST(PHYPARAM0_REF_LOSLEVEL, + PHYPARAM0_REF_LOSLEVEL_VAL); writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM0); reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); /* Set Tx De-Emphasis level */ - reg &= ~PHYPARAM1_PCS_TXDEEMPH_MASK; - reg |= PHYPARAM1_PCS_TXDEEMPH; + reg &= ~PHYPARAM1_PCS_TXDEEMPH; + reg |= FIELD_PREP_CONST(PHYPARAM1_PCS_TXDEEMPH, + PHYPARAM1_PCS_TXDEEMPH_VAL); writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); /* UTMI Power Control */ @@ -787,7 +792,7 @@ static int exynos5_usbdrd_phy_init(struct phy *phy) * See xHCI 1.0 spec, 5.2.4 */ reg = LINKSYSTEM_XHCI_VERSION_CONTROL | - LINKSYSTEM_FLADJ(0x20); + FIELD_PREP_CONST(LINKSYSTEM_FLADJ, 0x20); writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_LINKSYSTEM); reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM0); @@ -946,26 +951,24 @@ static int crport_handshake(struct exynos5_usbdrd_phy *phy_drd, static int crport_ctrl_write(struct exynos5_usbdrd_phy *phy_drd, u32 addr, u32 data) { + u32 val; int ret; /* Write Address */ - writel(PHYREG0_CR_DATA_IN(addr), - phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0); - ret = crport_handshake(phy_drd, PHYREG0_CR_DATA_IN(addr), - PHYREG0_CR_CAP_ADDR); + val = FIELD_PREP(PHYREG0_CR_DATA_IN, addr); + writel(val, phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0); + ret = crport_handshake(phy_drd, val, PHYREG0_CR_CAP_ADDR); if (ret) return ret; /* Write Data */ - writel(PHYREG0_CR_DATA_IN(data), - phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0); - ret = crport_handshake(phy_drd, PHYREG0_CR_DATA_IN(data), - PHYREG0_CR_CAP_DATA); + val = FIELD_PREP(PHYREG0_CR_DATA_IN, data); + writel(val, phy_drd->reg_phy + EXYNOS5_DRD_PHYREG0); + ret = crport_handshake(phy_drd, val, PHYREG0_CR_CAP_DATA); if (ret) return ret; - ret = crport_handshake(phy_drd, PHYREG0_CR_DATA_IN(data), - PHYREG0_CR_WRITE); + ret = crport_handshake(phy_drd, val, PHYREG0_CR_WRITE); return ret; } @@ -1134,7 +1137,7 @@ static void exynos850_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) /* Set VBUS Valid and D+ pull-up control by VBUS pad usage */ reg = readl(regs_base + EXYNOS850_DRD_LINKCTRL); - reg |= LINKCTRL_BUS_FILTER_BYPASS(0xf); + reg |= FIELD_PREP_CONST(LINKCTRL_BUS_FILTER_BYPASS, 0xf); writel(reg, regs_base + EXYNOS850_DRD_LINKCTRL); if (!phy_drd->sw) { @@ -1151,19 +1154,19 @@ static void exynos850_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) reg &= ~SSPPLLCTL_FSEL; switch (phy_drd->extrefclk) { case EXYNOS5_FSEL_50MHZ: - reg |= FIELD_PREP(SSPPLLCTL_FSEL, 7); + reg |= FIELD_PREP_CONST(SSPPLLCTL_FSEL, 7); break; case EXYNOS5_FSEL_26MHZ: - reg |= FIELD_PREP(SSPPLLCTL_FSEL, 6); + reg |= FIELD_PREP_CONST(SSPPLLCTL_FSEL, 6); break; case EXYNOS5_FSEL_24MHZ: - reg |= FIELD_PREP(SSPPLLCTL_FSEL, 2); + reg |= FIELD_PREP_CONST(SSPPLLCTL_FSEL, 2); break; case EXYNOS5_FSEL_20MHZ: - reg |= FIELD_PREP(SSPPLLCTL_FSEL, 1); + reg |= FIELD_PREP_CONST(SSPPLLCTL_FSEL, 1); break; case EXYNOS5_FSEL_19MHZ2: - reg |= FIELD_PREP(SSPPLLCTL_FSEL, 0); + reg |= FIELD_PREP_CONST(SSPPLLCTL_FSEL, 0); break; default: dev_warn(phy_drd->dev, "unsupported ref clk: %#.2x\n", -- 2.51.0 From 23f793850e9ee7390584c0809f085d6c88de7d3f Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Thu, 10 Apr 2025 14:01:13 +0530 Subject: [PATCH 03/16] dt-bindings: phy: samsung,usb3-drd-phy: add exynos7870-usbdrd-phy compatible Add the compatible string "samsung,exynos7870-usbdrd-phy" to the documentation. The devicetree node requires two clocks, named "phy" and "ref" (same as clocks required by Exynos5). Signed-off-by: Kaustabh Chakraborty Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250410-exynos7870-usbphy-v2-2-2eb005987455@disroot.org Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml index 27295acbba76..fdddddc7d611 100644 --- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml +++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml @@ -30,6 +30,7 @@ properties: - samsung,exynos5420-usbdrd-phy - samsung,exynos5433-usbdrd-phy - samsung,exynos7-usbdrd-phy + - samsung,exynos7870-usbdrd-phy - samsung,exynos850-usbdrd-phy clocks: @@ -184,6 +185,7 @@ allOf: enum: - samsung,exynos5250-usbdrd-phy - samsung,exynos5420-usbdrd-phy + - samsung,exynos7870-usbdrd-phy - samsung,exynos850-usbdrd-phy then: properties: -- 2.51.0 From 588d5d20ca8defa5ba5d1b536ff3695f6ab7aa87 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Thu, 10 Apr 2025 14:01:14 +0530 Subject: [PATCH 04/16] phy: exynos5-usbdrd: add exynos7870 USBDRD support Implement support for Exynos7870 USB DRD on top of the existing exynos5-usbdrd driver. Exynos7870 has a single USB 2.0 DRD PHY controller and no 3.0 PHYs. Thus, it only supports the UTMI interface. Moreover, the PMU register offset for enabling the PHY controller is different for SoCs such as Exynos7870, where BIT(0) is for the 3.0 PHY and BIT(1) is for the 2.0 PHY. The phy_isol function for Exynos7870 uses the appropriate register offsets. Signed-off-by: Kaustabh Chakraborty Link: https://lore.kernel.org/r/20250410-exynos7870-usbphy-v2-3-2eb005987455@disroot.org Signed-off-by: Vinod Koul --- drivers/phy/samsung/phy-exynos5-usbdrd.c | 260 ++++++++++++++++++++ include/linux/soc/samsung/exynos-regs-pmu.h | 2 + 2 files changed, 262 insertions(+) diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c index 534ccea93795..634c4310c660 100644 --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c @@ -39,10 +39,22 @@ /* Exynos5: USB 3.0 DRD PHY registers */ #define EXYNOS5_DRD_LINKSYSTEM 0x04 #define LINKSYSTEM_XHCI_VERSION_CONTROL BIT(27) +#define LINKSYSTEM_FORCE_VBUSVALID BIT(8) +#define LINKSYSTEM_FORCE_BVALID BIT(7) #define LINKSYSTEM_FLADJ GENMASK(6, 1) #define EXYNOS5_DRD_PHYUTMI 0x08 +#define PHYUTMI_UTMI_SUSPEND_COM_N BIT(12) +#define PHYUTMI_UTMI_L1_SUSPEND_COM_N BIT(11) +#define PHYUTMI_VBUSVLDEXTSEL BIT(10) +#define PHYUTMI_VBUSVLDEXT BIT(9) +#define PHYUTMI_TXBITSTUFFENH BIT(8) +#define PHYUTMI_TXBITSTUFFEN BIT(7) #define PHYUTMI_OTGDISABLE BIT(6) +#define PHYUTMI_IDPULLUP BIT(5) +#define PHYUTMI_DRVVBUS BIT(4) +#define PHYUTMI_DPPULLDOWN BIT(3) +#define PHYUTMI_DMPULLDOWN BIT(2) #define PHYUTMI_FORCESUSPEND BIT(1) #define PHYUTMI_FORCESLEEP BIT(0) @@ -91,6 +103,16 @@ #define PHYPARAM0_REF_USE_PAD BIT(31) #define PHYPARAM0_REF_LOSLEVEL GENMASK(30, 26) #define PHYPARAM0_REF_LOSLEVEL_VAL 0x9 +#define PHYPARAM0_TXVREFTUNE GENMASK(25, 22) +#define PHYPARAM0_TXRISETUNE GENMASK(21, 20) +#define PHYPARAM0_TXRESTUNE GENMASK(19, 18) +#define PHYPARAM0_TXPREEMPPULSETUNE BIT(17) +#define PHYPARAM0_TXPREEMPAMPTUNE GENMASK(16, 15) +#define PHYPARAM0_TXHSXVTUNE GENMASK(14, 13) +#define PHYPARAM0_TXFSLSTUNE GENMASK(12, 9) +#define PHYPARAM0_SQRXTUNE GENMASK(8, 6) +#define PHYPARAM0_OTGTUNE GENMASK(5, 3) +#define PHYPARAM0_COMPDISTUNE GENMASK(2, 0) #define EXYNOS5_DRD_PHYPARAM1 0x20 #define PHYPARAM1_PCS_TXDEEMPH GENMASK(4, 0) @@ -110,6 +132,12 @@ #define EXYNOS5_DRD_PHYRESUME 0x34 #define EXYNOS5_DRD_LINKPORT 0x44 +#define LINKPORT_HOST_U3_PORT_DISABLE BIT(8) +#define LINKPORT_HOST_U2_PORT_DISABLE BIT(7) +#define LINKPORT_HOST_PORT_OVCR_U3 BIT(5) +#define LINKPORT_HOST_PORT_OVCR_U2 BIT(4) +#define LINKPORT_HOST_PORT_OVCR_U3_SEL BIT(3) +#define LINKPORT_HOST_PORT_OVCR_U2_SEL BIT(2) /* USB 3.0 DRD PHY SS Function Control Reg; accessed by CR_PORT */ #define EXYNOS5_DRD_PHYSS_LOSLEVEL_OVRD_IN (0x15) @@ -130,6 +158,24 @@ #define LANE0_TX_DEBUG_RXDET_MEAS_TIME_62M5 (0x20 << 4) #define LANE0_TX_DEBUG_RXDET_MEAS_TIME_96M_100M (0x40 << 4) +/* Exynos7870: USB DRD PHY registers */ +#define EXYNOS7870_DRD_PHYPCSVAL 0x3C +#define PHYPCSVAL_PCS_RX_LOS_MASK GENMASK(9, 0) + +#define EXYNOS7870_DRD_PHYPARAM2 0x50 +#define PHYPARAM2_TX_VBOOST_LVL GENMASK(6, 4) +#define PHYPARAM2_LOS_BIAS GENMASK(2, 0) + +#define EXYNOS7870_DRD_HSPHYCTRL 0x54 +#define HSPHYCTRL_PHYSWRSTALL BIT(31) +#define HSPHYCTRL_SIDDQ BIT(6) +#define HSPHYCTRL_PHYSWRST BIT(0) + +#define EXYNOS7870_DRD_HSPHYPLLTUNE 0x70 +#define HSPHYPLLTUNE_PLL_B_TUNE BIT(6) +#define HSPHYPLLTUNE_PLL_I_TUNE GENMASK(5, 4) +#define HSPHYPLLTUNE_PLL_P_TUNE GENMASK(3, 0) + /* Exynos850: USB DRD PHY registers */ #define EXYNOS850_DRD_LINKCTRL 0x04 #define LINKCTRL_FORCE_RXELECIDLE BIT(18) @@ -1078,6 +1124,172 @@ static const struct phy_ops exynos5_usbdrd_phy_ops = { .owner = THIS_MODULE, }; +static void exynos7870_usbdrd_phy_isol(struct phy_usb_instance *inst, + bool isolate) +{ + unsigned int val; + + if (!inst->reg_pmu) + return; + + val = isolate ? 0 : EXYNOS7870_USB2PHY_ENABLE; + + regmap_update_bits(inst->reg_pmu, inst->pmu_offset, + EXYNOS7870_USB2PHY_ENABLE, val); +} + +static void exynos7870_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) +{ + u32 reg; + + reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); + /* Use PADREFCLK as ref clock */ + reg &= ~PHYCLKRST_REFCLKSEL; + reg |= FIELD_PREP_CONST(PHYCLKRST_REFCLKSEL, + PHYCLKRST_REFCLKSEL_PAD_REFCLK); + /* Select ref clock rate */ + reg &= ~PHYCLKRST_FSEL_UTMI; + reg &= ~PHYCLKRST_FSEL_PIPE; + reg |= FIELD_PREP(PHYCLKRST_FSEL_UTMI, phy_drd->extrefclk); + /* Enable suspend and reset the port */ + reg |= PHYCLKRST_EN_UTMISUSPEND; + reg |= PHYCLKRST_COMMONONN; + reg |= PHYCLKRST_PORTRESET; + writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); + udelay(10); + + /* Clear the port reset bit */ + reg &= ~PHYCLKRST_PORTRESET; + writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); + + /* Change PHY PLL tune value */ + reg = readl(phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYPLLTUNE); + if (phy_drd->extrefclk == EXYNOS5_FSEL_24MHZ) + reg |= HSPHYPLLTUNE_PLL_B_TUNE; + else + reg &= ~HSPHYPLLTUNE_PLL_B_TUNE; + reg &= ~HSPHYPLLTUNE_PLL_P_TUNE; + reg |= FIELD_PREP_CONST(HSPHYPLLTUNE_PLL_P_TUNE, 14); + writel(reg, phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYPLLTUNE); + + /* High-Speed PHY control */ + reg = readl(phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYCTRL); + reg &= ~HSPHYCTRL_SIDDQ; + reg &= ~HSPHYCTRL_PHYSWRST; + reg &= ~HSPHYCTRL_PHYSWRSTALL; + writel(reg, phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYCTRL); + udelay(500); + + reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_LINKSYSTEM); + /* + * Setting the Frame length Adj value[6:1] to default 0x20 + * See xHCI 1.0 spec, 5.2.4 + */ + reg |= LINKSYSTEM_XHCI_VERSION_CONTROL; + reg |= FIELD_PREP_CONST(LINKSYSTEM_FLADJ, 0x20); + /* Set VBUSVALID signal as the VBUS pad is not used */ + reg |= LINKSYSTEM_FORCE_BVALID; + reg |= LINKSYSTEM_FORCE_VBUSVALID; + writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_LINKSYSTEM); + + reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMI); + /* Release force_sleep & force_suspend */ + reg &= ~PHYUTMI_FORCESLEEP; + reg &= ~PHYUTMI_FORCESUSPEND; + /* DP/DM pull down control */ + reg &= ~PHYUTMI_DMPULLDOWN; + reg &= ~PHYUTMI_DPPULLDOWN; + reg &= ~PHYUTMI_DRVVBUS; + /* Set DP-pull up as the VBUS pad is not used */ + reg |= PHYUTMI_VBUSVLDEXTSEL; + reg |= PHYUTMI_VBUSVLDEXT; + /* Disable OTG block and VBUS valid comparator */ + reg |= PHYUTMI_OTGDISABLE; + writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMI); + + /* Configure OVC IO usage */ + reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_LINKPORT); + reg |= LINKPORT_HOST_PORT_OVCR_U3_SEL | LINKPORT_HOST_PORT_OVCR_U2_SEL; + writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_LINKPORT); + + /* High-Speed PHY swrst */ + reg = readl(phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYCTRL); + reg |= HSPHYCTRL_PHYSWRST; + writel(reg, phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYCTRL); + udelay(20); + + /* Clear the PHY swrst bit */ + reg = readl(phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYCTRL); + reg &= ~HSPHYCTRL_PHYSWRST; + writel(reg, phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYCTRL); + + if (phy_drd->drv_data->phy_tunes) + exynos5_usbdrd_apply_phy_tunes(phy_drd, + PTS_UTMI_POSTINIT); +} + +static int exynos7870_usbdrd_phy_init(struct phy *phy) +{ + struct phy_usb_instance *inst = phy_get_drvdata(phy); + struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); + int ret; + + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks); + if (ret) + return ret; + + /* UTMI or PIPE3 specific init */ + inst->phy_cfg->phy_init(phy_drd); + + clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks); + + return 0; +} + +static int exynos7870_usbdrd_phy_exit(struct phy *phy) +{ + int ret; + u32 reg; + struct phy_usb_instance *inst = phy_get_drvdata(phy); + struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); + + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks); + if (ret) + return ret; + + /* + * Disable the VBUS signal and the ID pull-up resistor. + * Enable force-suspend and force-sleep modes. + */ + reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMI); + reg &= ~(PHYUTMI_DRVVBUS | PHYUTMI_VBUSVLDEXT | PHYUTMI_VBUSVLDEXTSEL); + reg &= ~PHYUTMI_IDPULLUP; + reg |= PHYUTMI_FORCESUSPEND | PHYUTMI_FORCESLEEP; + writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYUTMI); + + /* Power down PHY analog blocks */ + reg = readl(phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYCTRL); + reg |= HSPHYCTRL_SIDDQ; + writel(reg, phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYCTRL); + + /* Clear VBUSVALID signal as the VBUS pad is not used */ + reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_LINKSYSTEM); + reg &= ~(LINKSYSTEM_FORCE_BVALID | LINKSYSTEM_FORCE_VBUSVALID); + writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_LINKSYSTEM); + + clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks); + + return 0; +} + +static const struct phy_ops exynos7870_usbdrd_phy_ops = { + .init = exynos7870_usbdrd_phy_init, + .exit = exynos7870_usbdrd_phy_exit, + .power_on = exynos5_usbdrd_phy_power_on, + .power_off = exynos5_usbdrd_phy_power_off, + .owner = THIS_MODULE, +}; + static void exynos5_usbdrd_usb_v3p1_pipe_override(struct exynos5_usbdrd_phy *phy_drd) { @@ -1504,6 +1716,14 @@ static const struct exynos5_usbdrd_phy_config phy_cfg_exynos5[] = { }, }; +static const struct exynos5_usbdrd_phy_config phy_cfg_exynos7870[] = { + { + .id = EXYNOS5_DRDPHY_UTMI, + .phy_isol = exynos7870_usbdrd_phy_isol, + .phy_init = exynos7870_usbdrd_utmi_init, + }, +}; + static const struct exynos5_usbdrd_phy_config phy_cfg_exynos850[] = { { .id = EXYNOS5_DRDPHY_UTMI, @@ -1512,6 +1732,30 @@ static const struct exynos5_usbdrd_phy_config phy_cfg_exynos850[] = { }, }; +static +const struct exynos5_usbdrd_phy_tuning exynos7870_tunes_utmi_postinit[] = { + PHY_TUNING_ENTRY_PHY(EXYNOS5_DRD_PHYPARAM0, + (PHYPARAM0_TXVREFTUNE | PHYPARAM0_TXRISETUNE | + PHYPARAM0_TXRESTUNE | PHYPARAM0_TXPREEMPPULSETUNE | + PHYPARAM0_TXPREEMPAMPTUNE | PHYPARAM0_TXHSXVTUNE | + PHYPARAM0_TXFSLSTUNE | PHYPARAM0_SQRXTUNE | + PHYPARAM0_OTGTUNE | PHYPARAM0_COMPDISTUNE), + (FIELD_PREP_CONST(PHYPARAM0_TXVREFTUNE, 14) | + FIELD_PREP_CONST(PHYPARAM0_TXRISETUNE, 1) | + FIELD_PREP_CONST(PHYPARAM0_TXRESTUNE, 3) | + FIELD_PREP_CONST(PHYPARAM0_TXPREEMPAMPTUNE, 0) | + FIELD_PREP_CONST(PHYPARAM0_TXHSXVTUNE, 0) | + FIELD_PREP_CONST(PHYPARAM0_TXFSLSTUNE, 3) | + FIELD_PREP_CONST(PHYPARAM0_SQRXTUNE, 6) | + FIELD_PREP_CONST(PHYPARAM0_OTGTUNE, 2) | + FIELD_PREP_CONST(PHYPARAM0_COMPDISTUNE, 3))), + PHY_TUNING_ENTRY_LAST +}; + +static const struct exynos5_usbdrd_phy_tuning *exynos7870_tunes[PTS_MAX] = { + [PTS_UTMI_POSTINIT] = exynos7870_tunes_utmi_postinit, +}; + static const char * const exynos5_clk_names[] = { "phy", }; @@ -1578,6 +1822,19 @@ static const struct exynos5_usbdrd_phy_drvdata exynos7_usbdrd_phy = { .n_regulators = ARRAY_SIZE(exynos5_regulator_names), }; +static const struct exynos5_usbdrd_phy_drvdata exynos7870_usbdrd_phy = { + .phy_cfg = phy_cfg_exynos7870, + .phy_tunes = exynos7870_tunes, + .phy_ops = &exynos7870_usbdrd_phy_ops, + .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, + .clk_names = exynos5_clk_names, + .n_clks = ARRAY_SIZE(exynos5_clk_names), + .core_clk_names = exynos5_core_clk_names, + .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), + .regulator_names = exynos5_regulator_names, + .n_regulators = ARRAY_SIZE(exynos5_regulator_names), +}; + static const struct exynos5_usbdrd_phy_drvdata exynos850_usbdrd_phy = { .phy_cfg = phy_cfg_exynos850, .phy_ops = &exynos850_usbdrd_phy_ops, @@ -1784,6 +2041,9 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = { }, { .compatible = "samsung,exynos7-usbdrd-phy", .data = &exynos7_usbdrd_phy + }, { + .compatible = "samsung,exynos7870-usbdrd-phy", + .data = &exynos7870_usbdrd_phy }, { .compatible = "samsung,exynos850-usbdrd-phy", .data = &exynos850_usbdrd_phy diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h index ce1a3790d6fb..cde299a85384 100644 --- a/include/linux/soc/samsung/exynos-regs-pmu.h +++ b/include/linux/soc/samsung/exynos-regs-pmu.h @@ -55,6 +55,8 @@ #define EXYNOS4_MIPI_PHY_SRESETN (1 << 1) #define EXYNOS4_MIPI_PHY_MRESETN (1 << 2) #define EXYNOS4_MIPI_PHY_RESET_MASK (3 << 1) +/* USB PHY enable bit, valid for Exynos7870 */ +#define EXYNOS7870_USB2PHY_ENABLE (1 << 1) #define S5P_INFORM0 0x0800 #define S5P_INFORM1 0x0804 -- 2.51.0 From ff02c5a3df4852819d9ec218e5c8ae48eb02b101 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 29 Mar 2025 20:07:11 +0100 Subject: [PATCH 05/16] phy: amlogic: meson8b-usb2: Use FIELD_PREP instead of _SHIFT macros This simplifies the code by re-using the FIELD_PREP helper. No functional changes inteded. Reviewed-by: Neil Armstrong Signed-off-by: Martin Blumenstingl Reviewed-by: Anand Moon Link: https://lore.kernel.org/r/20250329190712.858349-2-martin.blumenstingl@googlemail.com Signed-off-by: Vinod Koul --- drivers/phy/amlogic/phy-meson8b-usb2.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/phy/amlogic/phy-meson8b-usb2.c b/drivers/phy/amlogic/phy-meson8b-usb2.c index d63147c41b8c..d9c761b7c15c 100644 --- a/drivers/phy/amlogic/phy-meson8b-usb2.c +++ b/drivers/phy/amlogic/phy-meson8b-usb2.c @@ -5,6 +5,7 @@ * Copyright (C) 2016 Martin Blumenstingl */ +#include #include #include #include @@ -39,9 +40,7 @@ #define REG_CTRL_TX_BITSTUFF_ENN BIT(18) #define REG_CTRL_COMMON_ON BIT(19) #define REG_CTRL_REF_CLK_SEL_MASK GENMASK(21, 20) - #define REG_CTRL_REF_CLK_SEL_SHIFT 20 #define REG_CTRL_FSEL_MASK GENMASK(24, 22) - #define REG_CTRL_FSEL_SHIFT 22 #define REG_CTRL_PORT_RESET BIT(25) #define REG_CTRL_THREAD_ID_MASK GENMASK(31, 26) @@ -170,10 +169,10 @@ static int phy_meson8b_usb2_power_on(struct phy *phy) REG_CONFIG_CLK_32k_ALTSEL); regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_REF_CLK_SEL_MASK, - 0x2 << REG_CTRL_REF_CLK_SEL_SHIFT); + FIELD_PREP(REG_CTRL_REF_CLK_SEL_MASK, 0x2)); regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_FSEL_MASK, - 0x5 << REG_CTRL_FSEL_SHIFT); + FIELD_PREP(REG_CTRL_FSEL_MASK, 0x5)); /* reset the PHY */ regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET, -- 2.51.0 From e60363bcfbcef903ef30540776f254f8b53bb4c5 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 29 Mar 2025 20:07:12 +0100 Subject: [PATCH 06/16] phy: amlogic: meson8b-usb2: Use the regmap_{clear,set}_bits helpers These require less code, reduce the chance of typos and overall make the intent clearer. No functional changes. Reviewed-by: Neil Armstrong Signed-off-by: Martin Blumenstingl Reviewed-by: Anand Moon Link: https://lore.kernel.org/r/20250329190712.858349-3-martin.blumenstingl@googlemail.com Signed-off-by: Vinod Koul --- drivers/phy/amlogic/phy-meson8b-usb2.c | 28 ++++++++++---------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/drivers/phy/amlogic/phy-meson8b-usb2.c b/drivers/phy/amlogic/phy-meson8b-usb2.c index d9c761b7c15c..a553231a9f7c 100644 --- a/drivers/phy/amlogic/phy-meson8b-usb2.c +++ b/drivers/phy/amlogic/phy-meson8b-usb2.c @@ -165,8 +165,7 @@ static int phy_meson8b_usb2_power_on(struct phy *phy) return ret; } - regmap_update_bits(priv->regmap, REG_CONFIG, REG_CONFIG_CLK_32k_ALTSEL, - REG_CONFIG_CLK_32k_ALTSEL); + regmap_set_bits(priv->regmap, REG_CONFIG, REG_CONFIG_CLK_32k_ALTSEL); regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_REF_CLK_SEL_MASK, FIELD_PREP(REG_CTRL_REF_CLK_SEL_MASK, 0x2)); @@ -175,23 +174,20 @@ static int phy_meson8b_usb2_power_on(struct phy *phy) FIELD_PREP(REG_CTRL_FSEL_MASK, 0x5)); /* reset the PHY */ - regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET, - REG_CTRL_POWER_ON_RESET); + regmap_set_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET); udelay(RESET_COMPLETE_TIME); - regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET, 0); + regmap_clear_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET); udelay(RESET_COMPLETE_TIME); - regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_SOF_TOGGLE_OUT, - REG_CTRL_SOF_TOGGLE_OUT); + regmap_set_bits(priv->regmap, REG_CTRL, REG_CTRL_SOF_TOGGLE_OUT); if (priv->dr_mode == USB_DR_MODE_HOST) { - regmap_update_bits(priv->regmap, REG_DBG_UART, - REG_DBG_UART_SET_IDDQ, 0); + regmap_clear_bits(priv->regmap, REG_DBG_UART, + REG_DBG_UART_SET_IDDQ); if (priv->match->host_enable_aca) { - regmap_update_bits(priv->regmap, REG_ADP_BC, - REG_ADP_BC_ACA_ENABLE, - REG_ADP_BC_ACA_ENABLE); + regmap_set_bits(priv->regmap, REG_ADP_BC, + REG_ADP_BC_ACA_ENABLE); udelay(ACA_ENABLE_COMPLETE_TIME); @@ -214,17 +210,15 @@ static int phy_meson8b_usb2_power_off(struct phy *phy) struct phy_meson8b_usb2_priv *priv = phy_get_drvdata(phy); if (priv->dr_mode == USB_DR_MODE_HOST) - regmap_update_bits(priv->regmap, REG_DBG_UART, - REG_DBG_UART_SET_IDDQ, - REG_DBG_UART_SET_IDDQ); + regmap_set_bits(priv->regmap, REG_DBG_UART, + REG_DBG_UART_SET_IDDQ); clk_disable_unprepare(priv->clk_usb); clk_disable_unprepare(priv->clk_usb_general); reset_control_rearm(priv->reset); /* power off the PHY by putting it into reset mode */ - regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET, - REG_CTRL_POWER_ON_RESET); + regmap_set_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET); return 0; } -- 2.51.0 From be62baafc24105b3803fe7e09cfd23247588eb80 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 4 Apr 2025 14:13:25 +0200 Subject: [PATCH 07/16] phy: marvell: Do not enable by default during compile testing Enabling the compile test should not cause automatic enabling of all drivers. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250404121326.318936-1-krzysztof.kozlowski@linaro.org Signed-off-by: Vinod Koul --- drivers/phy/marvell/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/phy/marvell/Kconfig b/drivers/phy/marvell/Kconfig index bdb87c976243..bccd72dccb77 100644 --- a/drivers/phy/marvell/Kconfig +++ b/drivers/phy/marvell/Kconfig @@ -29,7 +29,7 @@ config PHY_MVEBU_A3700_COMPHY depends on ARCH_MVEBU || COMPILE_TEST depends on OF depends on HAVE_ARM_SMCCC - default y + default ARCH_MVEBU select GENERIC_PHY help This driver allows to control the comphy, a hardware block providing @@ -40,7 +40,7 @@ config PHY_MVEBU_A3700_UTMI tristate "Marvell A3700 UTMI driver" depends on ARCH_MVEBU || COMPILE_TEST depends on OF - default y + default ARCH_MVEBU select GENERIC_PHY help Enable this to support Marvell A3700 UTMI PHY driver. -- 2.51.0 From 6a9accd65608559c4e00ca5480e5d298bf329217 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 4 Apr 2025 14:13:26 +0200 Subject: [PATCH 08/16] phy: samsung: Do not enable PHY_EXYNOS5_USBDRD by default during compile testing Enabling the compile test should not cause automatic enabling of all drivers. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250404121326.318936-2-krzysztof.kozlowski@linaro.org Signed-off-by: Vinod Koul --- drivers/phy/samsung/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/samsung/Kconfig b/drivers/phy/samsung/Kconfig index 6566100441d6..b7ab402909a8 100644 --- a/drivers/phy/samsung/Kconfig +++ b/drivers/phy/samsung/Kconfig @@ -85,7 +85,7 @@ config PHY_EXYNOS5_USBDRD depends on USB_DWC3_EXYNOS select GENERIC_PHY select MFD_SYSCON - default y + default ARCH_EXYNOS help Enable USB DRD PHY support for Exynos 5 SoC series. This driver provides PHY interface for USB 3.0 DRD controller -- 2.51.0 From 0fbceff4f873500f0d0e632ee2d1e84e9a67b1b4 Mon Sep 17 00:00:00 2001 From: Justin Chen Date: Wed, 2 Apr 2025 11:51:58 -0700 Subject: [PATCH 09/16] dt-bindings: phy: brcmstb-usb-phy: Add support for bcm74110 bcm74110 brcmstb usb phy adds further power savings during suspend states. Signed-off-by: Justin Chen Reviewed-by: Florian Fainelli Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250402185159.2976920-2-justin.chen@broadcom.com Signed-off-by: Vinod Koul --- .../devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml b/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml index 580fbe37b37f..843d04027c30 100644 --- a/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml +++ b/Documentation/devicetree/bindings/phy/brcm,brcmstb-usb-phy.yaml @@ -18,6 +18,7 @@ properties: - brcm,bcm4908-usb-phy - brcm,bcm7211-usb-phy - brcm,bcm7216-usb-phy + - brcm,bcm74110-usb-phy - brcm,brcmstb-usb-phy reg: @@ -139,7 +140,9 @@ allOf: properties: compatible: contains: - const: brcm,bcm7216-usb-phy + enum: + - brcm,bcm7216-usb-phy + - brcm,bcm74110-usb-phy then: properties: reg: -- 2.51.0 From 686b2730e4816e40e6a5432ff163993638397154 Mon Sep 17 00:00:00 2001 From: Justin Chen Date: Wed, 2 Apr 2025 11:51:59 -0700 Subject: [PATCH 10/16] phy: usb: add support for bcm74110 bcm74110 adds a freerun utmi/ref clock that saves further power during suspend states. A tune is also necessary to pass USB compliance test. Signed-off-by: Justin Chen Reviewed-by: Florian Fainelli Link: https://lore.kernel.org/r/20250402185159.2976920-3-justin.chen@broadcom.com Signed-off-by: Vinod Koul --- .../phy/broadcom/phy-brcm-usb-init-synopsys.c | 61 +++++++++++++++++++ drivers/phy/broadcom/phy-brcm-usb-init.h | 1 + drivers/phy/broadcom/phy-brcm-usb.c | 14 +++++ 3 files changed, 76 insertions(+) diff --git a/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c b/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c index dc452610934a..8a5ed50f2da0 100644 --- a/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c +++ b/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c @@ -43,6 +43,8 @@ #define USB_CTRL_SETUP_tca_drv_sel_MASK BIT(24) #define USB_CTRL_SETUP_STRAP_IPP_SEL_MASK BIT(25) #define USB_CTRL_USB_PM 0x04 +#define USB_CTRL_USB_PM_REF_S2_CLK_SWITCH_EN_MASK BIT(1) +#define USB_CTRL_USB_PM_UTMI_S2_CLK_SWITCH_EN_MASK BIT(2) #define USB_CTRL_USB_PM_XHC_S2_CLK_SWITCH_EN_MASK BIT(3) #define USB_CTRL_USB_PM_XHC_PME_EN_MASK BIT(4) #define USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK BIT(22) @@ -61,6 +63,13 @@ #define USB_CTRL_CTLR_CSHCR_ctl_pme_en_MASK BIT(18) #define USB_CTRL_P0_U2PHY_CFG1 0x68 #define USB_CTRL_P0_U2PHY_CFG1_COMMONONN_MASK BIT(10) +#define USB_CTRL_P0_U2PHY_CFG2 0x6c +#define USB_CTRL_P0_U2PHY_CFG2_TXVREFTUNE0_MASK GENMASK(20, 17) +#define USB_CTRL_P0_U2PHY_CFG2_TXVREFTUNE0_SHIFT 17 +#define USB_CTRL_P0_U2PHY_CFG2_TXRESTUNE0_MASK GENMASK(24, 23) +#define USB_CTRL_P0_U2PHY_CFG2_TXRESTUNE0_SHIFT 23 +#define USB_CTRL_P0_U2PHY_CFG2_TXPREEMPAMPTUNE0_MASK GENMASK(26, 25) +#define USB_CTRL_P0_U2PHY_CFG2_TXPREEMPAMPTUNE0_SHIFT 25 /* Register definitions for the USB_PHY block in 7211b0 */ #define USB_PHY_PLL_CTL 0x00 @@ -369,6 +378,42 @@ static void usb_uninit_common_7216(struct brcm_usb_init_params *params) } } +static void usb_init_common_74110(struct brcm_usb_init_params *params) +{ + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; + u32 reg; + + reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_PM)); + reg &= ~(USB_CTRL_MASK(USB_PM, REF_S2_CLK_SWITCH_EN) | + USB_CTRL_MASK(USB_PM, UTMI_S2_CLK_SWITCH_EN)); + brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_PM)); + + usb_init_common_7216(params); + + reg = brcm_usb_readl(USB_CTRL_REG(ctrl, P0_U2PHY_CFG2)); + reg &= ~(USB_CTRL_P0_U2PHY_CFG2_TXVREFTUNE0_MASK | + USB_CTRL_P0_U2PHY_CFG2_TXRESTUNE0_MASK | + USB_CTRL_P0_U2PHY_CFG2_TXPREEMPAMPTUNE0_MASK); + reg |= (0x6 << USB_CTRL_P0_U2PHY_CFG2_TXVREFTUNE0_SHIFT) | + (0x3 << USB_CTRL_P0_U2PHY_CFG2_TXRESTUNE0_SHIFT) | + (0x2 << USB_CTRL_P0_U2PHY_CFG2_TXPREEMPAMPTUNE0_SHIFT); + brcm_usb_writel(reg, USB_CTRL_REG(ctrl, P0_U2PHY_CFG2)); +} + +static void usb_uninit_common_74110(struct brcm_usb_init_params *params) +{ + void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; + u32 reg; + + if (params->wake_enabled) { + reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_PM)); + reg |= (USB_CTRL_MASK(USB_PM, REF_S2_CLK_SWITCH_EN) | + USB_CTRL_MASK(USB_PM, UTMI_S2_CLK_SWITCH_EN)); + brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_PM)); + } + usb_uninit_common_7216(params); +} + static void usb_uninit_common_7211b0(struct brcm_usb_init_params *params) { void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; @@ -426,6 +471,16 @@ static void usb_set_dual_select(struct brcm_usb_init_params *params) brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1)); } +static const struct brcm_usb_init_ops bcm74110_ops = { + .init_ipp = usb_init_ipp, + .init_common = usb_init_common_74110, + .init_xhci = usb_init_xhci, + .uninit_common = usb_uninit_common_74110, + .uninit_xhci = usb_uninit_xhci, + .get_dual_select = usb_get_dual_select, + .set_dual_select = usb_set_dual_select, +}; + static const struct brcm_usb_init_ops bcm7216_ops = { .init_ipp = usb_init_ipp, .init_common = usb_init_common_7216, @@ -446,6 +501,12 @@ static const struct brcm_usb_init_ops bcm7211b0_ops = { .set_dual_select = usb_set_dual_select, }; +void brcm_usb_dvr_init_74110(struct brcm_usb_init_params *params) +{ + params->family_name = "74110"; + params->ops = &bcm74110_ops; +} + void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params) { diff --git a/drivers/phy/broadcom/phy-brcm-usb-init.h b/drivers/phy/broadcom/phy-brcm-usb-init.h index c1a88f5cd4cd..4c7be78d0b14 100644 --- a/drivers/phy/broadcom/phy-brcm-usb-init.h +++ b/drivers/phy/broadcom/phy-brcm-usb-init.h @@ -72,6 +72,7 @@ struct brcm_usb_init_params { bool wake_enabled; }; +void brcm_usb_dvr_init_74110(struct brcm_usb_init_params *params); void brcm_usb_dvr_init_4908(struct brcm_usb_init_params *params); void brcm_usb_dvr_init_7445(struct brcm_usb_init_params *params); void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params); diff --git a/drivers/phy/broadcom/phy-brcm-usb.c b/drivers/phy/broadcom/phy-brcm-usb.c index 6362ca5b7fb6..0666864c2f77 100644 --- a/drivers/phy/broadcom/phy-brcm-usb.c +++ b/drivers/phy/broadcom/phy-brcm-usb.c @@ -283,6 +283,16 @@ static const struct attribute_group brcm_usb_phy_group = { .attrs = brcm_usb_phy_attrs, }; +static const struct match_chip_info chip_info_74110 = { + .init_func = &brcm_usb_dvr_init_74110, + .required_regs = { + BRCM_REGS_CTRL, + BRCM_REGS_XHCI_EC, + BRCM_REGS_XHCI_GBL, + -1, + }, +}; + static const struct match_chip_info chip_info_4908 = { .init_func = &brcm_usb_dvr_init_4908, .required_regs = { @@ -325,6 +335,10 @@ static const struct match_chip_info chip_info_7445 = { }; static const struct of_device_id brcm_usb_dt_ids[] = { + { + .compatible = "brcm,bcm74110-usb-phy", + .data = &chip_info_74110, + }, { .compatible = "brcm,bcm4908-usb-phy", .data = &chip_info_4908, -- 2.51.0 From 05457917e50c3d6bf75d2e3b99c7e6709a4a6844 Mon Sep 17 00:00:00 2001 From: Anand Moon Date: Thu, 10 Apr 2025 19:03:16 +0530 Subject: [PATCH 11/16] phy: amlogic: phy-meson-gxl-usb2: Simplify error handling with dev_err_probe() Use dev_err_probe() for phy resources to indicate the deferral reason when waiting for the resource to come up. Signed-off-by: Anand Moon Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250410133332.294556-2-linux.amoon@gmail.com Signed-off-by: Vinod Koul --- drivers/phy/amlogic/phy-meson-gxl-usb2.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/phy/amlogic/phy-meson-gxl-usb2.c b/drivers/phy/amlogic/phy-meson-gxl-usb2.c index 14ea89927ab1..6b390304f723 100644 --- a/drivers/phy/amlogic/phy-meson-gxl-usb2.c +++ b/drivers/phy/amlogic/phy-meson-gxl-usb2.c @@ -237,7 +237,6 @@ static int phy_meson_gxl_usb2_probe(struct platform_device *pdev) struct phy_meson_gxl_usb2_priv *priv; struct phy *phy; void __iomem *base; - int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -266,13 +265,9 @@ static int phy_meson_gxl_usb2_probe(struct platform_device *pdev) return PTR_ERR(priv->reset); phy = devm_phy_create(dev, NULL, &phy_meson_gxl_usb2_ops); - if (IS_ERR(phy)) { - ret = PTR_ERR(phy); - if (ret != -EPROBE_DEFER) - dev_err(dev, "failed to create PHY\n"); - - return ret; - } + if (IS_ERR(phy)) + return dev_err_probe(dev, PTR_ERR(phy), + "failed to create PHY\n"); phy_set_drvdata(phy, priv); -- 2.51.0 From 9bff4ef29a6409850c27df705da54277a8e836f2 Mon Sep 17 00:00:00 2001 From: Anand Moon Date: Thu, 10 Apr 2025 19:03:17 +0530 Subject: [PATCH 12/16] phy: amlogic: phy-meson-g12a-usb2: Simplify error handling with dev_err_probe() Use dev_err_probe() for phy resources to indicate the deferral reason when waiting for the resource to come up. Signed-off-by: Anand Moon Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250410133332.294556-3-linux.amoon@gmail.com Signed-off-by: Vinod Koul --- drivers/phy/amlogic/phy-meson-g12a-usb2.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/phy/amlogic/phy-meson-g12a-usb2.c b/drivers/phy/amlogic/phy-meson-g12a-usb2.c index 0e0b5c00b676..66bf0b7ef8ed 100644 --- a/drivers/phy/amlogic/phy-meson-g12a-usb2.c +++ b/drivers/phy/amlogic/phy-meson-g12a-usb2.c @@ -339,13 +339,9 @@ static int phy_meson_g12a_usb2_probe(struct platform_device *pdev) return ret; phy = devm_phy_create(dev, NULL, &phy_meson_g12a_usb2_ops); - if (IS_ERR(phy)) { - ret = PTR_ERR(phy); - if (ret != -EPROBE_DEFER) - dev_err(dev, "failed to create PHY\n"); - - return ret; - } + if (IS_ERR(phy)) + return dev_err_probe(dev, PTR_ERR(phy), + "failed to create PHY\n"); phy_set_bus_width(phy, 8); phy_set_drvdata(phy, priv); -- 2.51.0 From de39730f9258e9984892c0af68a3e884ad19acea Mon Sep 17 00:00:00 2001 From: Anand Moon Date: Thu, 10 Apr 2025 19:03:18 +0530 Subject: [PATCH 13/16] phy: amlogic: phy-meson-axg-mipi-pcie-analog: Simplify error handling with dev_err_probe() Use dev_err_probe() for phy resources to indicate the deferral reason when waiting for the resource to come up. Signed-off-by: Anand Moon Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250410133332.294556-4-linux.amoon@gmail.com Signed-off-by: Vinod Koul --- drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c b/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c index ae898f93f97b..c0ba2852dbb8 100644 --- a/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c @@ -200,7 +200,6 @@ static int phy_axg_mipi_pcie_analog_probe(struct platform_device *pdev) struct phy_axg_mipi_pcie_analog_priv *priv; struct device_node *np = dev->of_node, *parent_np; struct regmap *map; - int ret; priv = devm_kmalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -219,12 +218,9 @@ static int phy_axg_mipi_pcie_analog_probe(struct platform_device *pdev) priv->regmap = map; priv->phy = devm_phy_create(dev, np, &phy_axg_mipi_pcie_analog_ops); - if (IS_ERR(priv->phy)) { - ret = PTR_ERR(priv->phy); - if (ret != -EPROBE_DEFER) - dev_err(dev, "failed to create PHY\n"); - return ret; - } + if (IS_ERR(priv->phy)) + return dev_err_probe(dev, PTR_ERR(priv->phy), + "failed to create PHY\n"); phy_set_drvdata(priv->phy, priv); dev_set_drvdata(dev, priv); -- 2.51.0 From a77e2e899841937798bff0924c03d4d0e4963aa3 Mon Sep 17 00:00:00 2001 From: Anand Moon Date: Thu, 10 Apr 2025 19:03:19 +0530 Subject: [PATCH 14/16] phy: amlogic: phy-meson-axg-mipi-dphy: Simplify error handling with dev_err_probe() Use dev_err_probe() for phy resources to indicate the deferral reason when waiting for the resource to come up. Signed-off-by: Anand Moon Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250410133332.294556-5-linux.amoon@gmail.com Signed-off-by: Vinod Koul --- drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c index 08a86962d949..c4a56b9d3289 100644 --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c @@ -377,13 +377,9 @@ static int phy_meson_axg_mipi_dphy_probe(struct platform_device *pdev) return ret; phy = devm_phy_create(dev, NULL, &phy_meson_axg_mipi_dphy_ops); - if (IS_ERR(phy)) { - ret = PTR_ERR(phy); - if (ret != -EPROBE_DEFER) - dev_err(dev, "failed to create PHY\n"); - - return ret; - } + if (IS_ERR(phy)) + return dev_err_probe(dev, PTR_ERR(phy), + "failed to create PHY\n"); phy_set_drvdata(phy, priv); -- 2.51.0 From fef364bd4c9cf712c91e0013f5f304f4e7f09198 Mon Sep 17 00:00:00 2001 From: Anand Moon Date: Thu, 10 Apr 2025 19:03:20 +0530 Subject: [PATCH 15/16] phy: amlogic: phy-meson-axg-pcie: Simplify error handling with dev_err_probe() Use dev_err_probe() for phy resources to indicate the deferral reason when waiting for the resource to come up. Signed-off-by: Anand Moon Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250410133332.294556-6-linux.amoon@gmail.com Signed-off-by: Vinod Koul --- drivers/phy/amlogic/phy-meson-axg-pcie.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/phy/amlogic/phy-meson-axg-pcie.c b/drivers/phy/amlogic/phy-meson-axg-pcie.c index 60be5cdc600b..54baf7b8930e 100644 --- a/drivers/phy/amlogic/phy-meson-axg-pcie.c +++ b/drivers/phy/amlogic/phy-meson-axg-pcie.c @@ -131,19 +131,15 @@ static int phy_axg_pcie_probe(struct platform_device *pdev) struct phy_axg_pcie_priv *priv; struct device_node *np = dev->of_node; void __iomem *base; - int ret; priv = devm_kmalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; priv->phy = devm_phy_create(dev, np, &phy_axg_pcie_ops); - if (IS_ERR(priv->phy)) { - ret = PTR_ERR(priv->phy); - if (ret != -EPROBE_DEFER) - dev_err(dev, "failed to create PHY\n"); - return ret; - } + if (IS_ERR(priv->phy)) + return dev_err_probe(dev, PTR_ERR(priv->phy), + "failed to create PHY\n"); base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) -- 2.51.0 From bdeff6d8a211c832f5ce1a65aff17f4a5e6de00f Mon Sep 17 00:00:00 2001 From: Anand Moon Date: Thu, 10 Apr 2025 19:03:21 +0530 Subject: [PATCH 16/16] phy: amlogic: phy-meson-axg-pcie: Fix PHY creation order in axg-pcie probe Reorder the PHY creation in the axg-pcie probe function to ensure all the resource is mapped before creating the PHY. This change addresses the issue where the PHY creation was attempted before mapping the necessary resources, potentially causing failures. Signed-off-by: Anand Moon Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20250410133332.294556-7-linux.amoon@gmail.com Signed-off-by: Vinod Koul --- drivers/phy/amlogic/phy-meson-axg-pcie.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/phy/amlogic/phy-meson-axg-pcie.c b/drivers/phy/amlogic/phy-meson-axg-pcie.c index 54baf7b8930e..14dee73f9cb5 100644 --- a/drivers/phy/amlogic/phy-meson-axg-pcie.c +++ b/drivers/phy/amlogic/phy-meson-axg-pcie.c @@ -136,11 +136,6 @@ static int phy_axg_pcie_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - priv->phy = devm_phy_create(dev, np, &phy_axg_pcie_ops); - if (IS_ERR(priv->phy)) - return dev_err_probe(dev, PTR_ERR(priv->phy), - "failed to create PHY\n"); - base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); @@ -158,6 +153,11 @@ static int phy_axg_pcie_probe(struct platform_device *pdev) if (IS_ERR(priv->analog)) return PTR_ERR(priv->analog); + priv->phy = devm_phy_create(dev, np, &phy_axg_pcie_ops); + if (IS_ERR(priv->phy)) + return dev_err_probe(dev, PTR_ERR(priv->phy), + "failed to create PHY\n"); + phy_set_drvdata(priv->phy, priv); dev_set_drvdata(dev, priv); pphy = devm_of_phy_provider_register(dev, of_phy_simple_xlate); -- 2.51.0