From b484b25a486962b568ada1f55c1b96dfd96b912d Mon Sep 17 00:00:00 2001 From: Frank Wunderlich Date: Tue, 22 Apr 2025 15:24:27 +0200 Subject: [PATCH 01/16] dt-bindings: phy: mtk-xs-phy: support type switch by pericfg Add support for type switch by pericfg register between USB3/PCIe. Signed-off-by: Frank Wunderlich Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250422132438.15735-5-linux@fw-web.de Signed-off-by: Vinod Koul --- .../devicetree/bindings/phy/mediatek,xsphy.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/mediatek,xsphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,xsphy.yaml index 3b5253659e6f..0bed847bb4ad 100644 --- a/Documentation/devicetree/bindings/phy/mediatek,xsphy.yaml +++ b/Documentation/devicetree/bindings/phy/mediatek,xsphy.yaml @@ -151,6 +151,21 @@ patternProperties: minimum: 1 maximum: 31 + mediatek,syscon-type: + $ref: /schemas/types.yaml#/definitions/phandle-array + description: + A phandle to syscon used to access the register of type switch, + the field should always be 3 cells long. + items: + - items: + - description: + Phandle to phy type configuration system controller + - description: + Phy type configuration register offset + - description: + Index of config segment + enum: [0, 1, 2, 3] + required: - reg - clocks -- 2.51.0 From f85eb659a48cc2f0c98a122e760552b69e56c06f Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Tue, 22 Apr 2025 15:24:29 +0200 Subject: [PATCH 02/16] phy: mediatek: xsphy: support type switch by pericfg Patch from Sam Shih found in MediaTek SDK released under GPL. Get syscon and use it to set the PHY type. Extend support to PCIe and SGMII mode in addition to USB2 and USB3. Signed-off-by: Daniel Golle Signed-off-by: Frank Wunderlich Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20250422132438.15735-7-linux@fw-web.de Signed-off-by: Vinod Koul --- drivers/phy/mediatek/phy-mtk-xsphy.c | 85 +++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/drivers/phy/mediatek/phy-mtk-xsphy.c b/drivers/phy/mediatek/phy-mtk-xsphy.c index 7c248f5cfca5..c0ddb9273cc3 100644 --- a/drivers/phy/mediatek/phy-mtk-xsphy.c +++ b/drivers/phy/mediatek/phy-mtk-xsphy.c @@ -11,10 +11,12 @@ #include #include #include +#include #include #include #include #include +#include #include "phy-mtk-io.h" @@ -81,12 +83,22 @@ #define XSP_SR_COEF_DIVISOR 1000 #define XSP_FM_DET_CYCLE_CNT 1024 +/* PHY switch between pcie/usb3/sgmii */ +#define USB_PHY_SWITCH_CTRL 0x0 +#define RG_PHY_SW_TYPE GENMASK(3, 0) +#define RG_PHY_SW_PCIE 0x0 +#define RG_PHY_SW_USB3 0x1 +#define RG_PHY_SW_SGMII 0x2 + struct xsphy_instance { struct phy *phy; void __iomem *port_base; struct clk *ref_clk; /* reference clock of anolog phy */ u32 index; u32 type; + struct regmap *type_sw; + u32 type_sw_reg; + u32 type_sw_index; /* only for HQA test */ int efuse_intr; int efuse_tx_imp; @@ -259,6 +271,10 @@ static void phy_parse_property(struct mtk_xsphy *xsphy, inst->efuse_intr, inst->efuse_tx_imp, inst->efuse_rx_imp); break; + case PHY_TYPE_PCIE: + case PHY_TYPE_SGMII: + /* nothing to do */ + break; default: dev_err(xsphy->dev, "incompatible phy type\n"); return; @@ -305,6 +321,62 @@ static void u3_phy_props_set(struct mtk_xsphy *xsphy, RG_XTP_LN0_RX_IMPSEL, inst->efuse_rx_imp); } +/* type switch for usb3/pcie/sgmii */ +static int phy_type_syscon_get(struct xsphy_instance *instance, + struct device_node *dn) +{ + struct of_phandle_args args; + int ret; + + /* type switch function is optional */ + if (!of_property_present(dn, "mediatek,syscon-type")) + return 0; + + ret = of_parse_phandle_with_fixed_args(dn, "mediatek,syscon-type", + 2, 0, &args); + if (ret) + return ret; + + instance->type_sw_reg = args.args[0]; + instance->type_sw_index = args.args[1] & 0x3; /* <=3 */ + instance->type_sw = syscon_node_to_regmap(args.np); + of_node_put(args.np); + dev_info(&instance->phy->dev, "type_sw - reg %#x, index %d\n", + instance->type_sw_reg, instance->type_sw_index); + + return PTR_ERR_OR_ZERO(instance->type_sw); +} + +static int phy_type_set(struct xsphy_instance *instance) +{ + int type; + u32 offset; + + if (!instance->type_sw) + return 0; + + switch (instance->type) { + case PHY_TYPE_USB3: + type = RG_PHY_SW_USB3; + break; + case PHY_TYPE_PCIE: + type = RG_PHY_SW_PCIE; + break; + case PHY_TYPE_SGMII: + type = RG_PHY_SW_SGMII; + break; + case PHY_TYPE_USB2: + default: + return 0; + } + + offset = instance->type_sw_index * BITS_PER_BYTE; + regmap_update_bits(instance->type_sw, instance->type_sw_reg, + RG_PHY_SW_TYPE << offset, type << offset); + + return 0; +} + static int mtk_phy_init(struct phy *phy) { struct xsphy_instance *inst = phy_get_drvdata(phy); @@ -325,6 +397,10 @@ static int mtk_phy_init(struct phy *phy) case PHY_TYPE_USB3: u3_phy_props_set(xsphy, inst); break; + case PHY_TYPE_PCIE: + case PHY_TYPE_SGMII: + /* nothing to do, only used to set type */ + break; default: dev_err(xsphy->dev, "incompatible phy type\n"); clk_disable_unprepare(inst->ref_clk); @@ -403,12 +479,15 @@ static struct phy *mtk_phy_xlate(struct device *dev, inst->type = args->args[0]; if (!(inst->type == PHY_TYPE_USB2 || - inst->type == PHY_TYPE_USB3)) { + inst->type == PHY_TYPE_USB3 || + inst->type == PHY_TYPE_PCIE || + inst->type == PHY_TYPE_SGMII)) { dev_err(dev, "unsupported phy type: %d\n", inst->type); return ERR_PTR(-EINVAL); } phy_parse_property(xsphy, inst); + phy_type_set(inst); return inst->phy; } @@ -510,6 +589,10 @@ static int mtk_xsphy_probe(struct platform_device *pdev) dev_err(dev, "failed to get ref_clk(id-%d)\n", port); return PTR_ERR(inst->ref_clk); } + + retval = phy_type_syscon_get(inst, child_np); + if (retval) + return retval; } provider = devm_of_phy_provider_register(dev, mtk_phy_xlate); -- 2.51.0 From e00c9aea31035f46b04a13effaa801f8b3419d2a Mon Sep 17 00:00:00 2001 From: Siddharth Vadapalli Date: Fri, 11 Apr 2025 11:27:43 +0530 Subject: [PATCH 03/16] dt-bindings: phy: cadence-torrent: enable PHY_TYPE_USXGMII The Cadence Torrent SERDES supports USXGMII protocol. Hence, update the bindings to allow PHY_TYPE_USXGMII. Since PHY_TYPE_USXGMII has the value of "12" while the existing maximum allowed PHY TYPE is "9", switch back to using "enum" property in the bindings to account for this discontinuity. Signed-off-by: Siddharth Vadapalli Acked-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20250411055743.623135-1-s-vadapalli@ti.com Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml b/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml index 15dc8efe6ffe..9af39b33646a 100644 --- a/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml +++ b/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml @@ -99,8 +99,7 @@ patternProperties: Specifies the type of PHY for which the group of PHY lanes is used. Refer include/dt-bindings/phy/phy.h. Constants from the header should be used. $ref: /schemas/types.yaml#/definitions/uint32 - minimum: 1 - maximum: 9 + enum: [1, 2, 3, 4, 5, 6, 7, 8, 9, 12] cdns,num-lanes: description: -- 2.51.0 From d14402a38c2d868cacb1facaf9be908ca6558e59 Mon Sep 17 00:00:00 2001 From: Chenyuan Yang Date: Mon, 14 Apr 2025 07:50:50 -0500 Subject: [PATCH 04/16] phy: qcom-qmp-usb: Fix an NULL vs IS_ERR() bug The qmp_usb_iomap() helper function currently returns the raw result of devm_ioremap() for non-exclusive mappings. Since devm_ioremap() may return a NULL pointer and the caller only checks error pointers with IS_ERR(), NULL could bypass the check and lead to an invalid dereference. Fix the issue by checking if devm_ioremap() returns NULL. When it does, qmp_usb_iomap() now returns an error pointer via IOMEM_ERR_PTR(-ENOMEM), ensuring safe and consistent error handling. Signed-off-by: Chenyuan Yang Fixes: a5d6b1ac56cb ("phy: qcom-qmp-usb: fix memleak on probe deferral") CC: Johan Hovold CC: Krzysztof Kozlowski Reviewed-by: Johan Hovold Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250414125050.2118619-1-chenyuan0y@gmail.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-qmp-usb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c index 787721570457..ed646a7e705b 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c @@ -2106,12 +2106,16 @@ static void __iomem *qmp_usb_iomap(struct device *dev, struct device_node *np, int index, bool exclusive) { struct resource res; + void __iomem *mem; if (!exclusive) { if (of_address_to_resource(np, index, &res)) return IOMEM_ERR_PTR(-EINVAL); - return devm_ioremap(dev, res.start, resource_size(&res)); + mem = devm_ioremap(dev, res.start, resource_size(&res)); + if (!mem) + return IOMEM_ERR_PTR(-ENOMEM); + return mem; } return devm_of_iomap(dev, np, index, NULL); -- 2.51.0 From 3b2b414927dcbd866c99ec92e3a214a69fc51c90 Mon Sep 17 00:00:00 2001 From: Chen Ni Date: Tue, 15 Apr 2025 16:12:00 +0800 Subject: [PATCH 05/16] phy: rockchip: samsung-hdptx: Remove unneeded semicolon Remove unnecessary semicolons reported by Coccinelle/coccicheck and the semantic patch at scripts/coccinelle/misc/semicolon.cocci. Signed-off-by: Chen Ni Link: https://lore.kernel.org/r/20250415081200.349939-1-nichen@iscas.ac.cn Signed-off-by: Vinod Koul --- drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c index fc289ed8d915..bb49d69a6f17 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c @@ -1507,7 +1507,7 @@ static int rk_hdptx_phy_verify_hdmi_config(struct rk_hdptx_phy *hdptx, break; default: return -EINVAL; - }; + } return 0; } -- 2.51.0 From 2063eedf3c9c4449fbf417c9b84ecd08251c3b34 Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Wed, 16 Apr 2025 15:24:17 -0500 Subject: [PATCH 06/16] dt-bindings: phy: rockchip: Convert RK3399 Type-C PHY to schema Convert the Rockchip RK3399 Type-C PHY to DT schema format. Add the missing "power-domains" property and "port" and "orientation-switch" properties in the child nodes. Omit the previously deprecated properties as they aren't used anywhere. Drop the 2nd example which was pretty much identical to the 1st example. Signed-off-by: Rob Herring (Arm) Acked-by: Greg Kroah-Hartman Reviewed-by: Heiko Stuebner Link: https://lore.kernel.org/r/20250416202419.3836688-1-robh@kernel.org Signed-off-by: Vinod Koul --- .../bindings/phy/phy-rockchip-typec.txt | 84 ------------- .../phy/rockchip,rk3399-typec-phy.yaml | 116 ++++++++++++++++++ .../bindings/usb/rockchip,dwc3.yaml | 2 +- 3 files changed, 117 insertions(+), 85 deletions(-) delete mode 100644 Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt create mode 100644 Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt b/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt deleted file mode 100644 index 960da7fcaa9e..000000000000 --- a/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt +++ /dev/null @@ -1,84 +0,0 @@ -* ROCKCHIP type-c PHY ---------------------- - -Required properties: - - compatible : must be "rockchip,rk3399-typec-phy" - - reg: Address and length of the usb phy control register set - - rockchip,grf : phandle to the syscon managing the "general - register files" - - clocks : phandle + clock specifier for the phy clocks - - clock-names : string, clock name, must be "tcpdcore", "tcpdphy-ref"; - - assigned-clocks: main clock, should be <&cru SCLK_UPHY0_TCPDCORE> or - <&cru SCLK_UPHY1_TCPDCORE>; - - assigned-clock-rates : the phy core clk frequency, shall be: 50000000 - - resets : a list of phandle + reset specifier pairs - - reset-names : string reset name, must be: - "uphy", "uphy-pipe", "uphy-tcphy" - -Optional properties: - - extcon : extcon specifier for the Power Delivery - -Required nodes : a sub-node is required for each port the phy provides. - The sub-node name is used to identify dp or usb3 port, - and shall be the following entries: - * "dp-port" : the name of DP port. - * "usb3-port" : the name of USB3 port. - -Required properties (port (child) node): -- #phy-cells : must be 0, See ./phy-bindings.txt for details. - -Deprecated properties, do not use in new device tree sources, these -properties are determined by the compatible value: - - rockchip,typec-conn-dir - - rockchip,usb3tousb2-en - - rockchip,external-psm - - rockchip,pipe-status - -Example: - tcphy0: phy@ff7c0000 { - compatible = "rockchip,rk3399-typec-phy"; - reg = <0x0 0xff7c0000 0x0 0x40000>; - rockchip,grf = <&grf>; - extcon = <&fusb0>; - clocks = <&cru SCLK_UPHY0_TCPDCORE>, - <&cru SCLK_UPHY0_TCPDPHY_REF>; - clock-names = "tcpdcore", "tcpdphy-ref"; - assigned-clocks = <&cru SCLK_UPHY0_TCPDCORE>; - assigned-clock-rates = <50000000>; - resets = <&cru SRST_UPHY0>, - <&cru SRST_UPHY0_PIPE_L00>, - <&cru SRST_P_UPHY0_TCPHY>; - reset-names = "uphy", "uphy-pipe", "uphy-tcphy"; - - tcphy0_dp: dp-port { - #phy-cells = <0>; - }; - - tcphy0_usb3: usb3-port { - #phy-cells = <0>; - }; - }; - - tcphy1: phy@ff800000 { - compatible = "rockchip,rk3399-typec-phy"; - reg = <0x0 0xff800000 0x0 0x40000>; - rockchip,grf = <&grf>; - extcon = <&fusb1>; - clocks = <&cru SCLK_UPHY1_TCPDCORE>, - <&cru SCLK_UPHY1_TCPDPHY_REF>; - clock-names = "tcpdcore", "tcpdphy-ref"; - assigned-clocks = <&cru SCLK_UPHY1_TCPDCORE>; - assigned-clock-rates = <50000000>; - resets = <&cru SRST_UPHY1>, - <&cru SRST_UPHY1_PIPE_L00>, - <&cru SRST_P_UPHY1_TCPHY>; - reset-names = "uphy", "uphy-pipe", "uphy-tcphy"; - - tcphy1_dp: dp-port { - #phy-cells = <0>; - }; - - tcphy1_usb3: usb3-port { - #phy-cells = <0>; - }; - }; diff --git a/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml new file mode 100644 index 000000000000..91c011f68cd0 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml @@ -0,0 +1,116 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/rockchip,rk3399-typec-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Rockchip Type-C PHY + +maintainers: + - Heiko Stuebner + +properties: + compatible: + const: rockchip,rk3399-typec-phy + + reg: + maxItems: 1 + + clocks: + maxItems: 2 + + clock-names: + items: + - const: tcpdcore + - const: tcpdphy-ref + + extcon: true + + power-domains: + maxItems: 1 + + resets: + maxItems: 3 + + reset-names: + items: + - const: uphy + - const: uphy-pipe + - const: uphy-tcphy + + rockchip,grf: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Phandle to the syscon managing the "general register files" (GRF). + + dp-port: + type: object + additionalProperties: false + + properties: + '#phy-cells': + const: 0 + + port: + $ref: /schemas/graph.yaml#/properties/port + description: Connection to USB Type-C connector + + required: + - '#phy-cells' + + usb3-port: + type: object + additionalProperties: false + + properties: + '#phy-cells': + const: 0 + + orientation-switch: true + + port: + $ref: /schemas/graph.yaml#/properties/port + description: Connection to USB Type-C connector SS port + + required: + - '#phy-cells' + +required: + - compatible + - reg + - clocks + - clock-names + - resets + - reset-names + - dp-port + - usb3-port + +additionalProperties: false + +examples: + - | + #include + + phy@ff7c0000 { + compatible = "rockchip,rk3399-typec-phy"; + reg = <0xff7c0000 0x40000>; + rockchip,grf = <&grf>; + extcon = <&fusb0>; + clocks = <&cru SCLK_UPHY0_TCPDCORE>, + <&cru SCLK_UPHY0_TCPDPHY_REF>; + clock-names = "tcpdcore", "tcpdphy-ref"; + resets = <&cru SRST_UPHY0>, + <&cru SRST_UPHY0_PIPE_L00>, + <&cru SRST_P_UPHY0_TCPHY>; + reset-names = "uphy", "uphy-pipe", "uphy-tcphy"; + + dp-port { + #phy-cells = <0>; + }; + + usb3-port { + #phy-cells = <0>; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/usb/rockchip,dwc3.yaml b/Documentation/devicetree/bindings/usb/rockchip,dwc3.yaml index fba2cb05ecba..fd1b13c0ed6b 100644 --- a/Documentation/devicetree/bindings/usb/rockchip,dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/rockchip,dwc3.yaml @@ -18,7 +18,7 @@ description: Documentation/devicetree/bindings/phy/rockchip,inno-usb2phy.yaml Type-C PHY - Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt + Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml select: properties: -- 2.51.0 From fe750a871d90e081c52ce1988e1fbc85576152a3 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Wed, 16 Apr 2025 14:02:19 +0200 Subject: [PATCH 07/16] dt-bindings: phy: mediatek,dsi-phy: Add support for MT6893 Add support for the MediaTek Dimensity 1200 (MT6893) SoC: the DSI PHY found in this chip is fully compatible with the one found in the MT8183 SoC. Signed-off-by: AngeloGioacchino Del Regno Acked-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20250416120220.147798-1-angelogioacchino.delregno@collabora.com Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml b/Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml index f6e494d0d89b..acdbce937b0a 100644 --- a/Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml +++ b/Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml @@ -30,6 +30,7 @@ properties: - const: mediatek,mt8173-mipi-tx - items: - enum: + - mediatek,mt6893-mipi-tx - mediatek,mt8188-mipi-tx - mediatek,mt8195-mipi-tx - mediatek,mt8365-mipi-tx -- 2.51.0 From 1b1e949924fb59e98d9401681b139e92e75686ac Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Wed, 16 Apr 2025 14:02:20 +0200 Subject: [PATCH 08/16] dt-bindings: phy: mediatek,tphy: Add support for MT6893 Add a compatible string for the MediaTek Dimensity 1200 (MT6893) SoC: this chip integrates a MediaTek generic T-PHY version 2. Signed-off-by: AngeloGioacchino Del Regno Acked-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20250416120220.147798-2-angelogioacchino.delregno@collabora.com Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/mediatek,tphy.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml index 6be3aa4557e5..b2218c151939 100644 --- a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml +++ b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml @@ -78,6 +78,7 @@ properties: - items: - enum: - mediatek,mt2712-tphy + - mediatek,mt6893-tphy - mediatek,mt7629-tphy - mediatek,mt7986-tphy - mediatek,mt8183-tphy -- 2.51.0 From 065d5885f6180c534b7b176847b3e008f4e11850 Mon Sep 17 00:00:00 2001 From: Mike Looijmans Date: Mon, 28 Apr 2025 08:35:47 +0200 Subject: [PATCH 09/16] phy-zynqmp: Postpone getting clock rate until actually needed At probe time the driver would display the following error and abort: xilinx-psgtr fd400000.phy: Invalid rate 0 for reference clock 0 At probe time, the associated GTR driver (e.g. SATA or PCIe) hasn't initialized the clock yet, so clk_get_rate() likely returns 0 if the clock is programmable. So this driver only works if the clock is fixed. The PHY driver doesn't need to know the clock frequency at probe yet, so wait until the associated driver initializes the lane before requesting the clock rate setting. In addition to allowing the driver to be used with programmable clocks, this also reduces the driver's runtime memory footprint by removing an array of pointers from struct xpsgtr_phy. Signed-off-by: Mike Looijmans Acked-by: Michal Simek Link: https://lore.kernel.org/r/20250428063648.22034-1-mike.looijmans@topic.nl Signed-off-by: Vinod Koul --- drivers/phy/xilinx/phy-zynqmp.c | 70 +++++++++++++++++---------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy-zynqmp.c index 05a4a59f7c40..fe6b4925d166 100644 --- a/drivers/phy/xilinx/phy-zynqmp.c +++ b/drivers/phy/xilinx/phy-zynqmp.c @@ -222,7 +222,6 @@ struct xpsgtr_phy { * @siou: siou base address * @gtr_mutex: mutex for locking * @phys: PHY lanes - * @refclk_sscs: spread spectrum settings for the reference clocks * @clk: reference clocks * @tx_term_fix: fix for GT issue * @saved_icm_cfg0: stored value of ICM CFG0 register @@ -235,7 +234,6 @@ struct xpsgtr_dev { void __iomem *siou; struct mutex gtr_mutex; /* mutex for locking */ struct xpsgtr_phy phys[NUM_LANES]; - const struct xpsgtr_ssc *refclk_sscs[NUM_LANES]; struct clk *clk[NUM_LANES]; bool tx_term_fix; unsigned int saved_icm_cfg0; @@ -398,13 +396,40 @@ got_phy: return ret; } +/* Get the spread spectrum (SSC) settings for the reference clock rate */ +static const struct xpsgtr_ssc *xpsgtr_find_sscs(struct xpsgtr_phy *gtr_phy) +{ + unsigned long rate; + struct clk *clk; + unsigned int i; + + clk = gtr_phy->dev->clk[gtr_phy->refclk]; + rate = clk_get_rate(clk); + + for (i = 0 ; i < ARRAY_SIZE(ssc_lookup); i++) { + /* Allow an error of 100 ppm */ + unsigned long error = ssc_lookup[i].refclk_rate / 10000; + + if (abs(rate - ssc_lookup[i].refclk_rate) < error) + return &ssc_lookup[i]; + } + + dev_err(gtr_phy->dev->dev, "Invalid rate %lu for reference clock %u\n", + rate, gtr_phy->refclk); + + return NULL; +} + /* Configure PLL and spread-sprectrum clock. */ -static void xpsgtr_configure_pll(struct xpsgtr_phy *gtr_phy) +static int xpsgtr_configure_pll(struct xpsgtr_phy *gtr_phy) { const struct xpsgtr_ssc *ssc; u32 step_size; - ssc = gtr_phy->dev->refclk_sscs[gtr_phy->refclk]; + ssc = xpsgtr_find_sscs(gtr_phy); + if (!ssc) + return -EINVAL; + step_size = ssc->step_size; xpsgtr_clr_set(gtr_phy->dev, PLL_REF_SEL(gtr_phy->lane), @@ -446,6 +471,8 @@ static void xpsgtr_configure_pll(struct xpsgtr_phy *gtr_phy) xpsgtr_clr_set_phy(gtr_phy, L0_PLL_SS_STEP_SIZE_3_MSB, STEP_SIZE_3_MASK, (step_size & STEP_SIZE_3_MASK) | FORCE_STEP_SIZE | FORCE_STEPS); + + return 0; } /* Configure the lane protocol. */ @@ -658,7 +685,10 @@ static int xpsgtr_phy_init(struct phy *phy) * Configure the PLL, the lane protocol, and perform protocol-specific * initialization. */ - xpsgtr_configure_pll(gtr_phy); + ret = xpsgtr_configure_pll(gtr_phy); + if (ret) + goto out; + xpsgtr_lane_set_protocol(gtr_phy); switch (gtr_phy->protocol) { @@ -823,8 +853,7 @@ static struct phy *xpsgtr_xlate(struct device *dev, } refclk = args->args[3]; - if (refclk >= ARRAY_SIZE(gtr_dev->refclk_sscs) || - !gtr_dev->refclk_sscs[refclk]) { + if (refclk >= ARRAY_SIZE(gtr_dev->clk)) { dev_err(dev, "Invalid reference clock number %u\n", refclk); return ERR_PTR(-EINVAL); } @@ -928,9 +957,7 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev) { unsigned int refclk; - for (refclk = 0; refclk < ARRAY_SIZE(gtr_dev->refclk_sscs); ++refclk) { - unsigned long rate; - unsigned int i; + for (refclk = 0; refclk < ARRAY_SIZE(gtr_dev->clk); ++refclk) { struct clk *clk; char name[8]; @@ -946,29 +973,6 @@ static int xpsgtr_get_ref_clocks(struct xpsgtr_dev *gtr_dev) continue; gtr_dev->clk[refclk] = clk; - - /* - * Get the spread spectrum (SSC) settings for the reference - * clock rate. - */ - rate = clk_get_rate(clk); - - for (i = 0 ; i < ARRAY_SIZE(ssc_lookup); i++) { - /* Allow an error of 100 ppm */ - unsigned long error = ssc_lookup[i].refclk_rate / 10000; - - if (abs(rate - ssc_lookup[i].refclk_rate) < error) { - gtr_dev->refclk_sscs[refclk] = &ssc_lookup[i]; - break; - } - } - - if (i == ARRAY_SIZE(ssc_lookup)) { - dev_err(gtr_dev->dev, - "Invalid rate %lu for reference clock %u\n", - rate, refclk); - return -EINVAL; - } } return 0; -- 2.51.0 From eb7a22f830f68997d76e660a02143c2bc72e7fb7 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 29 Apr 2025 09:54:40 +0200 Subject: [PATCH 10/16] phy: qcom: qmp-pcie: drop bogus x1e80100 qref supply The PCIe PHYs on x1e80100 do not a have a qref supply so stop requesting one. This also avoids the follow warning at boot: qcom-qmp-pcie-phy 1be0000.phy: supply vdda-qref not found, using dummy regulator Fixes: e961ec81a39b ("phy: qcom: qmp: Add phy register and clk setting for x1e80100 PCIe3") Cc: Qiang Yu Signed-off-by: Johan Hovold Reviewed-by: Abel Vesa Link: https://lore.kernel.org/r/20250429075440.19901-1-johan+linaro@kernel.org Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c index ab90aafb313e..461b9e0af610 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c @@ -4228,8 +4228,8 @@ static const struct qmp_phy_cfg x1e80100_qmp_gen4x8_pciephy_cfg = { .reset_list = sdm845_pciephy_reset_l, .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), - .vreg_list = sm8550_qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(sm8550_qmp_phy_vreg_l), + .vreg_list = qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), .regs = pciephy_v6_regs_layout, .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, -- 2.51.0 From b45791d48752418c805ae7417dcea85a40d5a41e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20Draszik?= Date: Tue, 29 Apr 2025 09:49:24 +0100 Subject: [PATCH 11/16] phy: exynos5-usbdrd: fix setting LINKSYSTEM_FLADJ on exynos7870 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The code here is trying to set the FLADJ field to 0x20, so it should clear any previous value in that field before or'ing-in the new value. Fixes: 588d5d20ca8d ("phy: exynos5-usbdrd: add exynos7870 USBDRD support") Signed-off-by: André Draszik Link: https://lore.kernel.org/r/20250429-exynos5-phy-field-prep-v1-1-39eb279a3e0e@linaro.org Signed-off-by: Vinod Koul --- drivers/phy/samsung/phy-exynos5-usbdrd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c index 634c4310c660..4ea1fabd4d6f 100644 --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c @@ -1186,6 +1186,7 @@ static void exynos7870_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) * See xHCI 1.0 spec, 5.2.4 */ reg |= LINKSYSTEM_XHCI_VERSION_CONTROL; + reg &= ~LINKSYSTEM_FLADJ; reg |= FIELD_PREP_CONST(LINKSYSTEM_FLADJ, 0x20); /* Set VBUSVALID signal as the VBUS pad is not used */ reg |= LINKSYSTEM_FORCE_BVALID; -- 2.51.0 From 6d0e2ada3ee5a554e908178d1fce851f5e63943d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20Draszik?= Date: Tue, 29 Apr 2025 09:49:25 +0100 Subject: [PATCH 12/16] phy: exynos5-usbdrd: s/FIELD_PREP_CONST/FIELD_PREP where appropriate MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Commit 9b6662a0f715 ("phy: exynos5-usbdrd: use GENMASK and FIELD_PREP for Exynos5 PHY registers") added FIELD_PREP_CONST() in many cases where FIELD_PREP() would have been more appropriate. It also switched existing uses of FIELD_PREP() to FIELD_PREP_CONST(). FIELD_PREP() is the preferred macro to use whenever possible while FIELD_PREP_CONST() is meant to be used in constant initialisers. Switch (back) to FIELD_PREP(). Fixes: 7e6c2ffe6c22 ("phy: exynos5-usbdrd: convert some FIELD_PREP_CONST() to FIELD_PREP()") Signed-off-by: André Draszik Link: https://lore.kernel.org/r/20250429-exynos5-phy-field-prep-v1-2-39eb279a3e0e@linaro.org Signed-off-by: Vinod Koul --- drivers/phy/samsung/phy-exynos5-usbdrd.c | 62 +++++++++++------------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c index 4ea1fabd4d6f..6cbe563a7bd0 100644 --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c @@ -540,8 +540,7 @@ exynos5_usbdrd_pipe3_set_refclk(struct phy_usb_instance *inst) /* Use EXTREFCLK as ref clock */ reg &= ~PHYCLKRST_REFCLKSEL; - reg |= FIELD_PREP_CONST(PHYCLKRST_REFCLKSEL, - PHYCLKRST_REFCLKSEL_EXT_REFCLK); + reg |= FIELD_PREP(PHYCLKRST_REFCLKSEL, PHYCLKRST_REFCLKSEL_EXT_REFCLK); /* FSEL settings corresponding to reference clock */ reg &= ~(PHYCLKRST_FSEL_PIPE | @@ -549,24 +548,24 @@ exynos5_usbdrd_pipe3_set_refclk(struct phy_usb_instance *inst) PHYCLKRST_SSC_REFCLKSEL); switch (phy_drd->extrefclk) { case EXYNOS5_FSEL_50MHZ: - reg |= (FIELD_PREP_CONST(PHYCLKRST_SSC_REFCLKSEL, 0x00) | - FIELD_PREP_CONST(PHYCLKRST_MPLL_MULTIPLIER, - PHYCLKRST_MPLL_MULTIPLIER_50M_REF)); + reg |= (FIELD_PREP(PHYCLKRST_SSC_REFCLKSEL, 0x00) | + FIELD_PREP(PHYCLKRST_MPLL_MULTIPLIER, + PHYCLKRST_MPLL_MULTIPLIER_50M_REF)); break; case EXYNOS5_FSEL_24MHZ: - reg |= (FIELD_PREP_CONST(PHYCLKRST_SSC_REFCLKSEL, 0x88) | - FIELD_PREP_CONST(PHYCLKRST_MPLL_MULTIPLIER, - PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF)); + reg |= (FIELD_PREP(PHYCLKRST_SSC_REFCLKSEL, 0x88) | + FIELD_PREP(PHYCLKRST_MPLL_MULTIPLIER, + PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF)); break; case EXYNOS5_FSEL_20MHZ: - reg |= (FIELD_PREP_CONST(PHYCLKRST_SSC_REFCLKSEL, 0x00) | - FIELD_PREP_CONST(PHYCLKRST_MPLL_MULTIPLIER, - PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF)); + reg |= (FIELD_PREP(PHYCLKRST_SSC_REFCLKSEL, 0x00) | + FIELD_PREP(PHYCLKRST_MPLL_MULTIPLIER, + PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF)); break; case EXYNOS5_FSEL_19MHZ2: - reg |= (FIELD_PREP_CONST(PHYCLKRST_SSC_REFCLKSEL, 0x88) | - FIELD_PREP_CONST(PHYCLKRST_MPLL_MULTIPLIER, - PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF)); + reg |= (FIELD_PREP(PHYCLKRST_SSC_REFCLKSEL, 0x88) | + FIELD_PREP(PHYCLKRST_MPLL_MULTIPLIER, + PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF)); break; default: dev_dbg(phy_drd->dev, "unsupported ref clk\n"); @@ -590,8 +589,7 @@ exynos5_usbdrd_utmi_set_refclk(struct phy_usb_instance *inst) reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYCLKRST); reg &= ~PHYCLKRST_REFCLKSEL; - reg |= FIELD_PREP_CONST(PHYCLKRST_REFCLKSEL, - PHYCLKRST_REFCLKSEL_EXT_REFCLK); + reg |= FIELD_PREP(PHYCLKRST_REFCLKSEL, PHYCLKRST_REFCLKSEL_EXT_REFCLK); reg &= ~(PHYCLKRST_FSEL_UTMI | PHYCLKRST_MPLL_MULTIPLIER | @@ -647,8 +645,7 @@ 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; - reg |= FIELD_PREP_CONST(PHYPARAM1_PCS_TXDEEMPH, - PHYPARAM1_PCS_TXDEEMPH_VAL); + reg |= FIELD_PREP(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); @@ -669,7 +666,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_CONST(SECPMACTL_PMA_REF_FREQ_SEL, 1); + reg |= FIELD_PREP(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 | @@ -799,15 +796,13 @@ 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; - reg |= FIELD_PREP_CONST(PHYPARAM0_REF_LOSLEVEL, - PHYPARAM0_REF_LOSLEVEL_VAL); + reg |= FIELD_PREP(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; - reg |= FIELD_PREP_CONST(PHYPARAM1_PCS_TXDEEMPH, - PHYPARAM1_PCS_TXDEEMPH_VAL); + reg |= FIELD_PREP(PHYPARAM1_PCS_TXDEEMPH, PHYPARAM1_PCS_TXDEEMPH_VAL); writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM1); /* UTMI Power Control */ @@ -838,7 +833,7 @@ static int exynos5_usbdrd_phy_init(struct phy *phy) * See xHCI 1.0 spec, 5.2.4 */ reg = LINKSYSTEM_XHCI_VERSION_CONTROL | - FIELD_PREP_CONST(LINKSYSTEM_FLADJ, 0x20); + FIELD_PREP(LINKSYSTEM_FLADJ, 0x20); writel(reg, phy_drd->reg_phy + EXYNOS5_DRD_LINKSYSTEM); reg = readl(phy_drd->reg_phy + EXYNOS5_DRD_PHYPARAM0); @@ -1145,8 +1140,7 @@ static void exynos7870_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) 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); + reg |= FIELD_PREP(PHYCLKRST_REFCLKSEL, PHYCLKRST_REFCLKSEL_PAD_REFCLK); /* Select ref clock rate */ reg &= ~PHYCLKRST_FSEL_UTMI; reg &= ~PHYCLKRST_FSEL_PIPE; @@ -1169,7 +1163,7 @@ static void exynos7870_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) else reg &= ~HSPHYPLLTUNE_PLL_B_TUNE; reg &= ~HSPHYPLLTUNE_PLL_P_TUNE; - reg |= FIELD_PREP_CONST(HSPHYPLLTUNE_PLL_P_TUNE, 14); + reg |= FIELD_PREP(HSPHYPLLTUNE_PLL_P_TUNE, 14); writel(reg, phy_drd->reg_phy + EXYNOS7870_DRD_HSPHYPLLTUNE); /* High-Speed PHY control */ @@ -1187,7 +1181,7 @@ static void exynos7870_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) */ reg |= LINKSYSTEM_XHCI_VERSION_CONTROL; reg &= ~LINKSYSTEM_FLADJ; - reg |= FIELD_PREP_CONST(LINKSYSTEM_FLADJ, 0x20); + reg |= FIELD_PREP(LINKSYSTEM_FLADJ, 0x20); /* Set VBUSVALID signal as the VBUS pad is not used */ reg |= LINKSYSTEM_FORCE_BVALID; reg |= LINKSYSTEM_FORCE_VBUSVALID; @@ -1350,7 +1344,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 |= FIELD_PREP_CONST(LINKCTRL_BUS_FILTER_BYPASS, 0xf); + reg |= FIELD_PREP(LINKCTRL_BUS_FILTER_BYPASS, 0xf); writel(reg, regs_base + EXYNOS850_DRD_LINKCTRL); if (!phy_drd->sw) { @@ -1367,19 +1361,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_CONST(SSPPLLCTL_FSEL, 7); + reg |= FIELD_PREP(SSPPLLCTL_FSEL, 7); break; case EXYNOS5_FSEL_26MHZ: - reg |= FIELD_PREP_CONST(SSPPLLCTL_FSEL, 6); + reg |= FIELD_PREP(SSPPLLCTL_FSEL, 6); break; case EXYNOS5_FSEL_24MHZ: - reg |= FIELD_PREP_CONST(SSPPLLCTL_FSEL, 2); + reg |= FIELD_PREP(SSPPLLCTL_FSEL, 2); break; case EXYNOS5_FSEL_20MHZ: - reg |= FIELD_PREP_CONST(SSPPLLCTL_FSEL, 1); + reg |= FIELD_PREP(SSPPLLCTL_FSEL, 1); break; case EXYNOS5_FSEL_19MHZ2: - reg |= FIELD_PREP_CONST(SSPPLLCTL_FSEL, 0); + reg |= FIELD_PREP(SSPPLLCTL_FSEL, 0); break; default: dev_warn(phy_drd->dev, "unsupported ref clk: %#.2x\n", -- 2.51.0 From 74c2524a51ab7a0539eb5ec64ee594c981f3d8a0 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Tue, 29 Apr 2025 11:01:52 +0200 Subject: [PATCH 13/16] phy: freescale: imx8m-pcie: Simplify with dev_err_probe() Error handling in probe() can be a bit simpler with dev_err_probe(). Signed-off-by: Alexander Stein Link: https://lore.kernel.org/r/20250429090152.1094243-1-alexander.stein@ew.tq-group.com Signed-off-by: Vinod Koul --- drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c index 7355d9921b64..68fcc8114d75 100644 --- a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c +++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c @@ -238,24 +238,21 @@ static int imx8_pcie_phy_probe(struct platform_device *pdev) imx8_phy->clkreq_unused = false; imx8_phy->clk = devm_clk_get(dev, "ref"); - if (IS_ERR(imx8_phy->clk)) { - dev_err(dev, "failed to get imx pcie phy clock\n"); - return PTR_ERR(imx8_phy->clk); - } + if (IS_ERR(imx8_phy->clk)) + return dev_err_probe(dev, PTR_ERR(imx8_phy->clk), + "failed to get imx pcie phy clock\n"); /* Grab GPR config register range */ imx8_phy->iomuxc_gpr = syscon_regmap_lookup_by_compatible(imx8_phy->drvdata->gpr); - if (IS_ERR(imx8_phy->iomuxc_gpr)) { - dev_err(dev, "unable to find iomuxc registers\n"); - return PTR_ERR(imx8_phy->iomuxc_gpr); - } + if (IS_ERR(imx8_phy->iomuxc_gpr)) + return dev_err_probe(dev, PTR_ERR(imx8_phy->iomuxc_gpr), + "unable to find iomuxc registers\n"); imx8_phy->reset = devm_reset_control_get_exclusive(dev, "pciephy"); - if (IS_ERR(imx8_phy->reset)) { - dev_err(dev, "Failed to get PCIEPHY reset control\n"); - return PTR_ERR(imx8_phy->reset); - } + if (IS_ERR(imx8_phy->reset)) + return dev_err_probe(dev, PTR_ERR(imx8_phy->reset), + "Failed to get PCIEPHY reset control\n"); if (imx8_phy->drvdata->variant == IMX8MP) { imx8_phy->perst = -- 2.51.0 From 8a040e13afd94a1f91acaf8e0505769d4f7f5af4 Mon Sep 17 00:00:00 2001 From: Kathiravan Thirumoorthy Date: Tue, 15 Apr 2025 09:52:50 +0530 Subject: [PATCH 14/16] Revert "phy: qcom-qusb2: add QUSB2 support for IPQ5424" With the current settings, compliance tests especially eye diagram (Host High-speed Signal Quality) tests are failing. Reuse the IPQ6018 settings to overcome this issue, as mentioned in the Hardware Design Document. So revert the change which introduced the new settings and reuse the IPQ6018 settings in the subsequent patch. Fixes: 9c56a1de296e ("phy: qcom-qusb2: add QUSB2 support for IPQ5424") Signed-off-by: Kathiravan Thirumoorthy Link: https://lore.kernel.org/r/20250415-revert_hs_phy_settings-v3-1-3a8f86211b59@oss.qualcomm.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-qusb2.c | 28 --------------------------- 1 file changed, 28 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c index 1f5f7df14d5a..81b9e9349c3e 100644 --- a/drivers/phy/qualcomm/phy-qcom-qusb2.c +++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c @@ -151,21 +151,6 @@ static const struct qusb2_phy_init_tbl ipq6018_init_tbl[] = { QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_AUTOPGM_CTL1, 0x9F), }; -static const struct qusb2_phy_init_tbl ipq5424_init_tbl[] = { - QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL, 0x14), - QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0x00), - QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0x53), - QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0xc3), - QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_TUNE, 0x30), - QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL1, 0x79), - QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL2, 0x21), - QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE5, 0x00), - QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00), - QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TEST2, 0x14), - QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_TEST, 0x80), - QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_AUTOPGM_CTL1, 0x9f), -}; - static const struct qusb2_phy_init_tbl qcs615_init_tbl[] = { QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0xc8), QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0xb3), @@ -359,16 +344,6 @@ static const struct qusb2_phy_cfg ipq6018_phy_cfg = { .autoresume_en = BIT(0), }; -static const struct qusb2_phy_cfg ipq5424_phy_cfg = { - .tbl = ipq5424_init_tbl, - .tbl_num = ARRAY_SIZE(ipq5424_init_tbl), - .regs = ipq6018_regs_layout, - - .disable_ctrl = POWER_DOWN, - .mask_core_ready = PLL_LOCKED, - .autoresume_en = BIT(0), -}; - static const struct qusb2_phy_cfg qcs615_phy_cfg = { .tbl = qcs615_init_tbl, .tbl_num = ARRAY_SIZE(qcs615_init_tbl), @@ -954,9 +929,6 @@ static const struct phy_ops qusb2_phy_gen_ops = { static const struct of_device_id qusb2_phy_of_match_table[] = { { - .compatible = "qcom,ipq5424-qusb2-phy", - .data = &ipq5424_phy_cfg, - }, { .compatible = "qcom,ipq6018-qusb2-phy", .data = &ipq6018_phy_cfg, }, { -- 2.51.0 From 25c36b54eafc98b3ef004e2037cea1328d9b8bc5 Mon Sep 17 00:00:00 2001 From: Kathiravan Thirumoorthy Date: Tue, 15 Apr 2025 09:52:51 +0530 Subject: [PATCH 15/16] phy: qcom-qusb2: reuse the IPQ6018 settings for IPQ5424 With the settings used in the commit 9c56a1de296e ("phy: qcom-qusb2: add QUSB2 support for IPQ5424"), compliance test cases especially eye-diagram (Host High-speed Signal Quality) tests are failing. Reuse the IPQ6018 settings for IPQ5424 as mentioned in the Hardware Design Document which helps to meet all the complaince requirement test cases. Fixes: 9c56a1de296e ("phy: qcom-qusb2: add QUSB2 support for IPQ5424") Signed-off-by: Kathiravan Thirumoorthy Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250415-revert_hs_phy_settings-v3-2-3a8f86211b59@oss.qualcomm.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-qusb2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c index 81b9e9349c3e..49c37c53b38e 100644 --- a/drivers/phy/qualcomm/phy-qcom-qusb2.c +++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c @@ -929,6 +929,9 @@ static const struct phy_ops qusb2_phy_gen_ops = { static const struct of_device_id qusb2_phy_of_match_table[] = { { + .compatible = "qcom,ipq5424-qusb2-phy", + .data = &ipq6018_phy_cfg, + }, { .compatible = "qcom,ipq6018-qusb2-phy", .data = &ipq6018_phy_cfg, }, { -- 2.51.0 From 5b3a91b207c00a8d27f75ce8aaa9860844da72c8 Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Wed, 30 Apr 2025 17:44:59 +0800 Subject: [PATCH 16/16] dt-bindings: phy: imx8mq-usb: fix fsl,phy-tx-vboost-level-microvolt property The ticket TKT0676370 shows the description of TX_VBOOST_LVL is wrong in register PHY_CTRL3 bit[31:29]. 011: Corresponds to a launch amplitude of 1.12 V. 010: Corresponds to a launch amplitude of 1.04 V. 000: Corresponds to a launch amplitude of 0.88 V. After updated: 011: Corresponds to a launch amplitude of 0.844 V. 100: Corresponds to a launch amplitude of 1.008 V. 101: Corresponds to a launch amplitude of 1.156 V. This will correct it accordingly. Fixes: b2e75563dc39 ("dt-bindings: phy: imx8mq-usb: add phy tuning properties") Cc: stable@vger.kernel.org Reviewed-by: Jun Li Signed-off-by: Xu Yang Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250430094502.2723983-1-xu.yang_2@nxp.com Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml index daee0c0fc915..c468207eb951 100644 --- a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml +++ b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml @@ -63,8 +63,7 @@ properties: fsl,phy-tx-vboost-level-microvolt: description: Adjust the boosted transmit launch pk-pk differential amplitude - minimum: 880 - maximum: 1120 + enum: [844, 1008, 1156] fsl,phy-comp-dis-tune-percent: description: -- 2.51.0