* [PATCH v2 0/2] Add support for SA8255P in the qcom-qmp-usb phy driver
@ 2026-07-09 14:52 Mattijs Korpershoek
2026-07-09 14:52 ` [PATCH v2 1/2] dt-bindings: phy: qcom,sc8280xp-qmp-usb3-uni: Add SA8255P USB PHY Mattijs Korpershoek
2026-07-09 14:52 ` [PATCH v2 2/2] phy: qcom: qmp-usb: Add support for SA8255P Mattijs Korpershoek
0 siblings, 2 replies; 7+ messages in thread
From: Mattijs Korpershoek @ 2026-07-09 14:52 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: Maxime Ripard, linux-arm-msm, linux-phy, devicetree, linux-kernel,
Mattijs Korpershoek, Sriram Dash, Shazad Hussain
The Qualcomm automotive SA8255p SoC relies on firmware to configure
platform resources, including clocks, interconnects and TLMM.
The driver requests resources operations over SCMI using power protocols.
The SCMI power protocol enables or disables resources like clocks,
interconnect paths, and TLMM (GPIOs) using runtime PM framework APIs,
such as resume/suspend, to control power on/off.
Power domain "core" controls the GDSC, resets, and TLMM (GPIOs)
whereas power domain "transfer" controls clocks and interconnects.
Patch 1 adds the binding change for sa8255p. I've considered to create
a totally separate binding like the I2C one [1].
Given that the existing binding already had multiple conditionals, I've
chosen to update qcom,sc8280xp-qmp-usb3-uni-phy.yaml by adding another
conditional for the power domains.
Patch 2 adds the driver change, which is based on a public vendor
patch from qualcomm [2].
I did the following changes on top of that:
* Use devm_add_action_or_reset() for dev_pm_domain_detach_list() instead
of implementing a driver .remove()
* Drop the .lanes struct member since it no longer exists.
* Re-order some functions
This has been tested on next-20260706 with a Ride4 SA8775P board that
has SCMI firmware (which is compatible).
[1] https://lore.kernel.org/all/20260617-enable-i2c-on-sa8255p-v7-1-ad736dbeab57@oss.qualcomm.com/
[2] https://git.codelinaro.org/clo/le/meta-qti-auto-kernel/-/blob/LY.AU.0.1.0.r1-16800-gen4meta.0/recipes-kernel/linux/files/usb/0011-PENDING-phy-qcom-qmp-usb-Add-support-for-SA8255P.patch
Signed-off-by: Mattijs Korpershoek <mkorpershoek@kernel.org>
---
Changes in v2:
* Driver changes:
* Fix comment typo tranfer -> transfer
* Fix print statement to add a missing '(' in the string
* Use dev_err_probe() in qmp_usb_domain_attach() to reduce log noise
* Fix pm_runtime_put_sync() order in qmp_usb_d0_to_d3 (Sashiko)
* Fix runtime PM reference leak on usb_transfer (Sashiko)
* Fix runtime PM reference leak on error in qmp_usb_init (Sashiko)
* Reorder qmp_usb_d0_to_d3() to mirror init ordering in qmp_usb_exit()
(Sashiko)
* Reorder qmp_usb_d0_to_d3() to mirror resume ordering in
qmp_usb_runtime_suspend() (Sashiko)
* Fix error handling in qmp_usb_runtime_resume() (Sashiko)
* Link to v1: https://patch.msgid.link/20260708-phy-qcom-qmp-usb-8255-v1-0-8d852a9535db@kernel.org
---
Mattijs Korpershoek (1):
dt-bindings: phy: qcom,sc8280xp-qmp-usb3-uni: Add SA8255P USB PHY
Sriram Dash (1):
phy: qcom: qmp-usb: Add support for SA8255P
.../phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml | 92 ++++++++++-
drivers/phy/qualcomm/phy-qcom-qmp-usb.c | 182 ++++++++++++++++++---
2 files changed, 243 insertions(+), 31 deletions(-)
---
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
change-id: 20260708-phy-qcom-qmp-usb-8255-9986907cdbc9
Best regards,
--
Mattijs Korpershoek <mkorpershoek@kernel.org>
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH v2 1/2] dt-bindings: phy: qcom,sc8280xp-qmp-usb3-uni: Add SA8255P USB PHY 2026-07-09 14:52 [PATCH v2 0/2] Add support for SA8255P in the qcom-qmp-usb phy driver Mattijs Korpershoek @ 2026-07-09 14:52 ` Mattijs Korpershoek 2026-07-11 17:13 ` Krzysztof Kozlowski 2026-07-09 14:52 ` [PATCH v2 2/2] phy: qcom: qmp-usb: Add support for SA8255P Mattijs Korpershoek 1 sibling, 1 reply; 7+ messages in thread From: Mattijs Korpershoek @ 2026-07-09 14:52 UTC (permalink / raw) To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley Cc: Maxime Ripard, linux-arm-msm, linux-phy, devicetree, linux-kernel, Mattijs Korpershoek SA8255p platform abstracts resources such as clocks, interconnect and GPIO pins configuration in Firmware. SCMI power protocol is used to request resource configurations. Two power domains can be requested: usb_transfer and usb_core. usb_transfer controls clocks and interconnects and usb_core controls the GDSC, resets and TLMM (GPIOs) Add compatible string for Qualcomm QMP Super Speed (SS) UNI PHY found in SA8255P. Add conditionals to make some properties (clocks, resets, supplies) optional for SA8255P while keeping them required for all other platforms. Finally, also add a new example to illustrate a firmware-managed node. Signed-off-by: Mattijs Korpershoek <mkorpershoek@kernel.org> --- .../phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml | 92 +++++++++++++++++++--- 1 file changed, 83 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml index 01342823e57f..80b04b7f7584 100644 --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml @@ -26,6 +26,7 @@ properties: - qcom,msm8996-qmp-usb3-phy - qcom,qcs8300-qmp-usb3-uni-phy - qcom,qdu1000-qmp-usb3-uni-phy + - qcom,sa8255p-qmp-usb3-uni-phy - qcom,sa8775p-qmp-usb3-uni-phy - qcom,sc8180x-qmp-usb3-uni-phy - qcom,sc8280xp-qmp-usb3-uni-phy @@ -54,7 +55,13 @@ properties: maxItems: 5 power-domains: - maxItems: 1 + minItems: 1 + maxItems: 2 + + power-domain-names: + items: + - const: usb_transfer + - const: usb_core resets: maxItems: 2 @@ -82,14 +89,6 @@ properties: required: - compatible - reg - - clocks - - clock-names - - resets - - reset-names - - vdda-phy-supply - - vdda-pll-supply - - "#clock-cells" - - clock-output-names - "#phy-cells" allOf: @@ -188,6 +187,66 @@ allOf: properties: refgen-supply: false + - if: + properties: + compatible: + contains: + enum: + - qcom,glymur-qmp-usb3-uni-phy + - qcom,ipq5424-qmp-usb3-phy + - qcom,ipq6018-qmp-usb3-phy + - qcom,ipq8074-qmp-usb3-phy + - qcom,ipq9574-qmp-usb3-phy + - qcom,msm8996-qmp-usb3-phy + - qcom,qcs8300-qmp-usb3-uni-phy + - qcom,qdu1000-qmp-usb3-uni-phy + - qcom,sa8775p-qmp-usb3-uni-phy + - qcom,sc8180x-qmp-usb3-uni-phy + - qcom,sc8280xp-qmp-usb3-uni-phy + - qcom,sdm845-qmp-usb3-uni-phy + - qcom,sdx55-qmp-usb3-uni-phy + - qcom,sdx65-qmp-usb3-uni-phy + - qcom,sdx75-qmp-usb3-uni-phy + - qcom,sm8150-qmp-usb3-uni-phy + - qcom,sm8250-qmp-usb3-uni-phy + - qcom,sm8350-qmp-usb3-uni-phy + - qcom,x1e80100-qmp-usb3-uni-phy + then: + properties: + power-domains: + maxItems: 1 + required: + - clocks + - clock-names + - resets + - reset-names + - vdda-phy-supply + - vdda-pll-supply + - "#clock-cells" + - clock-output-names + + - if: + properties: + compatible: + contains: + enum: + - qcom,sa8255p-qmp-usb3-uni-phy + then: + properties: + clocks: false + clock-names: false + resets: false + reset-names: false + vdda-phy-supply: false + vdda-pll-supply: false + "#clock-cells": false + clock-output-names: false + power-domains: + minItems: 2 + required: + - power-domains + - power-domain-names + additionalProperties: false examples: @@ -219,3 +278,18 @@ examples: #phy-cells = <0>; }; + + - | + soc { + #address-cells = <2>; + #size-cells = <2>; + + phy@88e8000 { + compatible = "qcom,sa8255p-qmp-usb3-uni-phy"; + reg = <0x0 0x088e8000 0x0 0x2000>; + #phy-cells = <0>; + + power-domains = <&scmi12_pd 2>, <&scmi12_pd 3>; + power-domain-names = "usb_transfer", "usb_core"; + }; + }; -- 2.54.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/2] dt-bindings: phy: qcom,sc8280xp-qmp-usb3-uni: Add SA8255P USB PHY 2026-07-09 14:52 ` [PATCH v2 1/2] dt-bindings: phy: qcom,sc8280xp-qmp-usb3-uni: Add SA8255P USB PHY Mattijs Korpershoek @ 2026-07-11 17:13 ` Krzysztof Kozlowski 2026-07-22 12:18 ` Mattijs Korpershoek 0 siblings, 1 reply; 7+ messages in thread From: Krzysztof Kozlowski @ 2026-07-11 17:13 UTC (permalink / raw) To: Mattijs Korpershoek Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Maxime Ripard, linux-arm-msm, linux-phy, devicetree, linux-kernel On Thu, Jul 09, 2026 at 04:52:09PM +0200, Mattijs Korpershoek wrote: > diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml > index 01342823e57f..80b04b7f7584 100644 > --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml > +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml > @@ -26,6 +26,7 @@ properties: > - qcom,msm8996-qmp-usb3-phy > - qcom,qcs8300-qmp-usb3-uni-phy > - qcom,qdu1000-qmp-usb3-uni-phy > + - qcom,sa8255p-qmp-usb3-uni-phy > - qcom,sa8775p-qmp-usb3-uni-phy > - qcom,sc8180x-qmp-usb3-uni-phy > - qcom,sc8280xp-qmp-usb3-uni-phy > @@ -54,7 +55,13 @@ properties: > maxItems: 5 > > power-domains: > - maxItems: 1 > + minItems: 1 > + maxItems: 2 > + > + power-domain-names: > + items: > + - const: usb_transfer > + - const: usb_core usb_ feels redundant, since this is USB phy. > > resets: > maxItems: 2 > @@ -82,14 +89,6 @@ properties: > required: > - compatible > - reg > - - clocks > - - clock-names > - - resets > - - reset-names > - - vdda-phy-supply > - - vdda-pll-supply > - - "#clock-cells" > - - clock-output-names > - "#phy-cells" Just like in all other saXXXX cases, same review: move to a separate binding file. Best regards, Krzysztof ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/2] dt-bindings: phy: qcom,sc8280xp-qmp-usb3-uni: Add SA8255P USB PHY 2026-07-11 17:13 ` Krzysztof Kozlowski @ 2026-07-22 12:18 ` Mattijs Korpershoek 0 siblings, 0 replies; 7+ messages in thread From: Mattijs Korpershoek @ 2026-07-22 12:18 UTC (permalink / raw) To: Krzysztof Kozlowski Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Maxime Ripard, linux-arm-msm, linux-phy, devicetree, linux-kernel Hi Krzysztof, Thank you for the review. On Sat, Jul 11, 2026 at 19:13, Krzysztof Kozlowski <krzk@kernel.org> wrote: > On Thu, Jul 09, 2026 at 04:52:09PM +0200, Mattijs Korpershoek wrote: >> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml >> index 01342823e57f..80b04b7f7584 100644 >> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml >> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml >> @@ -26,6 +26,7 @@ properties: >> - qcom,msm8996-qmp-usb3-phy >> - qcom,qcs8300-qmp-usb3-uni-phy >> - qcom,qdu1000-qmp-usb3-uni-phy >> + - qcom,sa8255p-qmp-usb3-uni-phy >> - qcom,sa8775p-qmp-usb3-uni-phy >> - qcom,sc8180x-qmp-usb3-uni-phy >> - qcom,sc8280xp-qmp-usb3-uni-phy >> @@ -54,7 +55,13 @@ properties: >> maxItems: 5 >> >> power-domains: >> - maxItems: 1 >> + minItems: 1 >> + maxItems: 2 >> + >> + power-domain-names: >> + items: >> + - const: usb_transfer >> + - const: usb_core > > usb_ feels redundant, since this is USB phy. Ack, will drop for v3. > >> >> resets: >> maxItems: 2 >> @@ -82,14 +89,6 @@ properties: >> required: >> - compatible >> - reg >> - - clocks >> - - clock-names >> - - resets >> - - reset-names >> - - vdda-phy-supply >> - - vdda-pll-supply >> - - "#clock-cells" >> - - clock-output-names >> - "#phy-cells" > > Just like in all other saXXXX cases, same review: move to a separate > binding file. Ack, I was not sure about this one. I'll move to a separate binding file in v3. > > Best regards, > Krzysztof ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 2/2] phy: qcom: qmp-usb: Add support for SA8255P 2026-07-09 14:52 [PATCH v2 0/2] Add support for SA8255P in the qcom-qmp-usb phy driver Mattijs Korpershoek 2026-07-09 14:52 ` [PATCH v2 1/2] dt-bindings: phy: qcom,sc8280xp-qmp-usb3-uni: Add SA8255P USB PHY Mattijs Korpershoek @ 2026-07-09 14:52 ` Mattijs Korpershoek 2026-07-09 15:06 ` sashiko-bot 1 sibling, 1 reply; 7+ messages in thread From: Mattijs Korpershoek @ 2026-07-09 14:52 UTC (permalink / raw) To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley Cc: Maxime Ripard, linux-arm-msm, linux-phy, devicetree, linux-kernel, Mattijs Korpershoek, Sriram Dash, Shazad Hussain From: Sriram Dash <quic_sriramd@quicinc.com> The Qualcomm automotive SA8255p SoC relies on firmware to configure platform resources, including clocks, interconnects and TLMM. The driver requests resources operations over SCMI using power protocols. The SCMI power protocol enables or disables resources like clocks, interconnect paths, and TLMM (GPIOs) using runtime PM framework APIs, such as resume/suspend, to control power on/off. Power domain "usb_core" controls the GDSC, resets, and TLMM (GPIOs) whereas power domain "usb_transfer" controls clocks and interconnects. In this variant, two disjoint sets of resources are modeled against the power domain suppliers which can be turned on/off to achieve modeled device states. Two modeled low power states d1 and d3 are supported. transition: d0 <--> d3 :: both core and transfer suppliers transition: d0 <--> d1 :: only transfer supplier Signed-off-by: Sriram Dash <quic_sriramd@quicinc.com> Signed-off-by: Shazad Hussain <quic_shazhuss@quicinc.com> Signed-off-by: Mattijs Korpershoek <mkorpershoek@kernel.org> --- drivers/phy/qualcomm/phy-qcom-qmp-usb.c | 182 ++++++++++++++++++++++++++++---- 1 file changed, 160 insertions(+), 22 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c index c5507168e135..d085c1ad7fb5 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c @@ -15,6 +15,7 @@ #include <linux/of_address.h> #include <linux/phy/phy.h> #include <linux/platform_device.h> +#include <linux/pm_domain.h> #include <linux/regulator/consumer.h> #include <linux/reset.h> #include <linux/slab.h> @@ -1411,6 +1412,9 @@ struct qmp_phy_cfg { /* Offset from PCS to PCS_USB region */ unsigned int pcs_usb_offset; + + /* true, if the device resources are fw managed */ + bool fw_managed; }; struct qmp_usb { @@ -1437,6 +1441,8 @@ struct qmp_usb { struct phy *phy; struct clk_fixed_rate pipe_clk_fixed; + + struct dev_pm_domain_list *pd_list; }; static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val) @@ -1667,6 +1673,25 @@ static const struct qmp_phy_cfg qcs8300_usb3_uniphy_cfg = { .regs = qmp_v5_usb3phy_regs_layout, }; +static const struct qmp_phy_cfg sa8255p_usb3_uniphy_cfg = { + .offsets = &qmp_usb_offsets_v5, + + .serdes_tbl = sc8280xp_usb3_uniphy_serdes_tbl, + .serdes_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_serdes_tbl), + .tx_tbl = sc8280xp_usb3_uniphy_tx_tbl, + .tx_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_tx_tbl), + .rx_tbl = sc8280xp_usb3_uniphy_rx_tbl, + .rx_tbl_num = ARRAY_SIZE(sc8280xp_usb3_uniphy_rx_tbl), + .pcs_tbl = sa8775p_usb3_uniphy_pcs_tbl, + .pcs_tbl_num = ARRAY_SIZE(sa8775p_usb3_uniphy_pcs_tbl), + .pcs_usb_tbl = sa8775p_usb3_uniphy_pcs_usb_tbl, + .pcs_usb_tbl_num = ARRAY_SIZE(sa8775p_usb3_uniphy_pcs_usb_tbl), + .vreg_list = qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .regs = qmp_v5_usb3phy_regs_layout, + .fw_managed = true, +}; + static const struct qmp_phy_cfg sc8280xp_usb3_uniphy_cfg = { .offsets = &qmp_usb_offsets_v5, @@ -1865,6 +1890,77 @@ static const struct qmp_phy_cfg glymur_usb3_uniphy_cfg = { .regs = qmp_v7_usb3phy_regs_layout, }; +static int qmp_usb_domain_attach(struct qmp_usb *qmp) +{ + struct dev_pm_domain_attach_data pd_data = { + .pd_flags = PD_FLAG_NO_DEV_LINK, + .pd_names = (const char *[]) { "usb_transfer", "usb_core" }, + .num_pd_names = 2, + }; + struct device *dev = qmp->dev; + int ret; + + ret = dev_pm_domain_attach_list(dev, &pd_data, &qmp->pd_list); + if (ret < 0) + return dev_err_probe(dev, ret, "domain attach failed\n"); + + return 0; +} + +static void qmp_usb_domain_detach(void *data) +{ + struct qmp_usb *qmp = data; + + dev_pm_domain_detach_list(qmp->pd_list); +} + +/* d3_to_d0 transition by turning on all the suppliers */ +static int qmp_usb_d3_to_d0(struct qmp_usb *qmp) +{ + int ret; + + if (!qmp->pd_list) + return 0; + + ret = pm_runtime_resume_and_get(qmp->pd_list->pd_devs[0]); + if (ret) + return ret; + + ret = pm_runtime_resume_and_get(qmp->pd_list->pd_devs[1]); + if (ret) + pm_runtime_put_sync(qmp->pd_list->pd_devs[0]); + + return ret; +} + +/* d0_to_d3 transition by turning off all the suppliers */ +static void qmp_usb_d0_to_d3(struct qmp_usb *qmp) +{ + if (!qmp->pd_list) + return; + + pm_runtime_put_sync(qmp->pd_list->pd_devs[1]); + pm_runtime_put_sync(qmp->pd_list->pd_devs[0]); +} + +/* d1_to_d0 transition by turning on the 'transfer' supplier */ +static int qmp_usb_d1_to_d0(struct qmp_usb *qmp) +{ + if (!qmp->pd_list) + return 0; + + return pm_runtime_resume_and_get(qmp->pd_list->pd_devs[0]); +} + +/* d0_to_d1 transition by turning off the 'transfer' supplier */ +static void qmp_usb_d0_to_d1(struct qmp_usb *qmp) +{ + if (!qmp->pd_list) + return; + + pm_runtime_put_sync(qmp->pd_list->pd_devs[0]); +} + static int qmp_usb_serdes_init(struct qmp_usb *qmp) { const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -1884,10 +1980,16 @@ static int qmp_usb_init(struct phy *phy) void __iomem *pcs = qmp->pcs; int ret; + ret = qmp_usb_d3_to_d0(qmp); + if (ret < 0) { + dev_err(qmp->dev, "Failed to transition to d0 state\n"); + return ret; + } + ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs); if (ret) { dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret); - return ret; + goto err_transition_to_d3; } ret = reset_control_bulk_assert(qmp->num_resets, qmp->resets); @@ -1914,6 +2016,8 @@ static int qmp_usb_init(struct phy *phy) reset_control_bulk_assert(qmp->num_resets, qmp->resets); err_disable_regulators: regulator_bulk_disable(cfg->num_vregs, qmp->vregs); +err_transition_to_d3: + qmp_usb_d0_to_d3(qmp); return ret; } @@ -1929,6 +2033,8 @@ static int qmp_usb_exit(struct phy *phy) regulator_bulk_disable(cfg->num_vregs, qmp->vregs); + qmp_usb_d0_to_d3(qmp); + return 0; } @@ -2111,6 +2217,8 @@ static int __maybe_unused qmp_usb_runtime_suspend(struct device *dev) clk_disable_unprepare(qmp->pipe_clk); clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks); + qmp_usb_d0_to_d1(qmp); + return 0; } @@ -2126,14 +2234,23 @@ static int __maybe_unused qmp_usb_runtime_resume(struct device *dev) return 0; } + ret = qmp_usb_d1_to_d0(qmp); + if (ret < 0) { + dev_err(qmp->dev, "Failed to transition to d0 state\n"); + return ret; + } + ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks); - if (ret) + if (ret) { + qmp_usb_d0_to_d1(qmp); return ret; + } ret = clk_prepare_enable(qmp->pipe_clk); if (ret) { dev_err(dev, "pipe_clk enable failed, err=%d\n", ret); clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks); + qmp_usb_d0_to_d1(qmp); return ret; } @@ -2313,10 +2430,12 @@ static int qmp_usb_parse_dt_legacy(struct qmp_usb *qmp, struct device_node *np) qmp->pcs_misc = NULL; } - qmp->pipe_clk = devm_get_clk_from_child(dev, np, NULL); - if (IS_ERR(qmp->pipe_clk)) { - return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk), - "failed to get pipe clock\n"); + if (!qmp->cfg->fw_managed) { + qmp->pipe_clk = devm_get_clk_from_child(dev, np, NULL); + if (IS_ERR(qmp->pipe_clk)) { + return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk), + "failed to get pipe clock\n"); + } } ret = devm_clk_bulk_get_all(qmp->dev, &qmp->clks); @@ -2325,10 +2444,12 @@ static int qmp_usb_parse_dt_legacy(struct qmp_usb *qmp, struct device_node *np) qmp->num_clks = ret; - ret = qmp_usb_reset_init(qmp, usb3phy_legacy_reset_l, - ARRAY_SIZE(usb3phy_legacy_reset_l)); - if (ret) - return ret; + if (!qmp->cfg->fw_managed) { + ret = qmp_usb_reset_init(qmp, usb3phy_legacy_reset_l, + ARRAY_SIZE(usb3phy_legacy_reset_l)); + if (ret) + return ret; + } return 0; } @@ -2362,17 +2483,19 @@ static int qmp_usb_parse_dt(struct qmp_usb *qmp) if (ret) return ret; - qmp->pipe_clk = devm_clk_get(dev, "pipe"); - if (IS_ERR(qmp->pipe_clk)) { - return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk), - "failed to get pipe clock\n"); + if (!qmp->cfg->fw_managed) { + qmp->pipe_clk = devm_clk_get(dev, "pipe"); + if (IS_ERR(qmp->pipe_clk)) { + return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk), + "failed to get pipe clock\n"); + } + + ret = qmp_usb_reset_init(qmp, usb3phy_reset_l, + ARRAY_SIZE(usb3phy_reset_l)); + if (ret) + return ret; } - ret = qmp_usb_reset_init(qmp, usb3phy_reset_l, - ARRAY_SIZE(usb3phy_reset_l)); - if (ret) - return ret; - return 0; } @@ -2395,6 +2518,16 @@ static int qmp_usb_probe(struct platform_device *pdev) if (!qmp->cfg) return -EINVAL; + if (qmp->cfg->fw_managed) { + ret = qmp_usb_domain_attach(qmp); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dev, qmp_usb_domain_detach, qmp); + if (ret) + return ret; + } + ret = devm_regulator_bulk_get_const(dev, qmp->cfg->num_vregs, qmp->cfg->vreg_list, &qmp->vregs); if (ret) @@ -2421,9 +2554,11 @@ static int qmp_usb_probe(struct platform_device *pdev) */ pm_runtime_forbid(dev); - ret = phy_pipe_clk_register(qmp, np); - if (ret) - goto err_node_put; + if (!qmp->cfg->fw_managed) { + ret = phy_pipe_clk_register(qmp, np); + if (ret) + goto err_node_put; + } qmp->phy = devm_phy_create(dev, np, &qmp_usb_phy_ops); if (IS_ERR(qmp->phy)) { @@ -2470,6 +2605,9 @@ static const struct of_device_id qmp_usb_of_match_table[] = { }, { .compatible = "qcom,qdu1000-qmp-usb3-uni-phy", .data = &qdu1000_usb3_uniphy_cfg, + }, { + .compatible = "qcom,sa8255p-qmp-usb3-uni-phy", + .data = &sa8255p_usb3_uniphy_cfg, }, { .compatible = "qcom,sa8775p-qmp-usb3-uni-phy", .data = &sa8775p_usb3_uniphy_cfg, -- 2.54.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 2/2] phy: qcom: qmp-usb: Add support for SA8255P 2026-07-09 14:52 ` [PATCH v2 2/2] phy: qcom: qmp-usb: Add support for SA8255P Mattijs Korpershoek @ 2026-07-09 15:06 ` sashiko-bot 2026-07-22 12:10 ` Mattijs Korpershoek 0 siblings, 1 reply; 7+ messages in thread From: sashiko-bot @ 2026-07-09 15:06 UTC (permalink / raw) To: Mattijs Korpershoek Cc: robh, neil.armstrong, conor+dt, olteanv, linux-phy, devicetree, vkoul Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [High] Incorrect power domain sequencing during d0/d3 transitions risks NoC errors and bus hangs. -- --- Patch [2]: [PATCH v2 2/2] phy: qcom: qmp-usb: Add support for SA8255P --- commit c32bbfd817c3f9fca4d2982ea37be36354501cc7 Author: Sriram Dash <quic_sriramd@quicinc.com> Subject: phy: qcom: qmp-usb: Add support for SA8255P This commit adds support for the SA8255P SoC to the QMP USB PHY driver. It introduces firmware-managed resources via SCMI using power protocols, managing state transitions (d0, d1, d3) through the "usb_core" and "usb_transfer" power domains. > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c > index c5507168e1354..d085c1ad7fb5c 100644 > --- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c [ ... ] > @@ -1865,6 +1890,77 @@ static const struct qmp_phy_cfg glymur_usb3_uniphy_cfg = { > .regs = qmp_v7_usb3phy_regs_layout, > }; [ ... ] > +/* d3_to_d0 transition by turning on all the suppliers */ > +static int qmp_usb_d3_to_d0(struct qmp_usb *qmp) > +{ > + int ret; > + > + if (!qmp->pd_list) > + return 0; > + > + ret = pm_runtime_resume_and_get(qmp->pd_list->pd_devs[0]); > + if (ret) > + return ret; > + > + ret = pm_runtime_resume_and_get(qmp->pd_list->pd_devs[1]); > + if (ret) > + pm_runtime_put_sync(qmp->pd_list->pd_devs[0]); > + > + return ret; > +} [Severity: High] Does this sequence power up the domains in the wrong order? The commit message notes that "usb_core" (which maps to pd_devs[1] based on the qmp_usb_domain_attach order) controls the GDSC, while "usb_transfer" (pd_devs[0]) controls clocks and interconnects. Enabling clocks before the GDSC foundational power domain is enabled typically results in unpowered register access on Qualcomm SoCs, which could trigger a Network-on-Chip (NoC) error and bus hang. Should pd_devs[1] be resumed before pd_devs[0]? > + > +/* d0_to_d3 transition by turning off all the suppliers */ > +static void qmp_usb_d0_to_d3(struct qmp_usb *qmp) > +{ > + if (!qmp->pd_list) > + return; > + > + pm_runtime_put_sync(qmp->pd_list->pd_devs[1]); > + pm_runtime_put_sync(qmp->pd_list->pd_devs[0]); > +} [Severity: High] Similarly, could this cause a bus hang during the d0 to d3 transition? Putting "usb_core" (pd_devs[1]) before "usb_transfer" (pd_devs[0]) disables the GDSC before the clocks. Shouldn't the GDSC be disabled last to prevent unpowered hardware clock access? -- Sashiko AI review · https://sashiko.dev/#/patchset/20260709-phy-qcom-qmp-usb-8255-v2-0-3b6c26a45788@kernel.org?part=2 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 2/2] phy: qcom: qmp-usb: Add support for SA8255P 2026-07-09 15:06 ` sashiko-bot @ 2026-07-22 12:10 ` Mattijs Korpershoek 0 siblings, 0 replies; 7+ messages in thread From: Mattijs Korpershoek @ 2026-07-22 12:10 UTC (permalink / raw) To: sashiko-reviews Cc: robh, neil.armstrong, conor+dt, olteanv, linux-phy, devicetree, vkoul On Thu, Jul 09, 2026 at 15:06, sashiko-bot@kernel.org wrote: > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: > - [High] Incorrect power domain sequencing during d0/d3 transitions risks NoC errors and bus hangs. > -- > > --- Patch [2]: [PATCH v2 2/2] phy: qcom: qmp-usb: Add support for SA8255P --- > commit c32bbfd817c3f9fca4d2982ea37be36354501cc7 > Author: Sriram Dash <quic_sriramd@quicinc.com> > Subject: phy: qcom: qmp-usb: Add support for SA8255P > > This commit adds support for the SA8255P SoC to the QMP USB PHY driver. > It introduces firmware-managed resources via SCMI using power protocols, > managing state transitions (d0, d1, d3) through the "usb_core" and > "usb_transfer" power domains. > >> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c >> index c5507168e1354..d085c1ad7fb5c 100644 >> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c >> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c > > [ ... ] > >> @@ -1865,6 +1890,77 @@ static const struct qmp_phy_cfg glymur_usb3_uniphy_cfg = { >> .regs = qmp_v7_usb3phy_regs_layout, >> }; > > [ ... ] > >> +/* d3_to_d0 transition by turning on all the suppliers */ >> +static int qmp_usb_d3_to_d0(struct qmp_usb *qmp) >> +{ >> + int ret; >> + >> + if (!qmp->pd_list) >> + return 0; >> + >> + ret = pm_runtime_resume_and_get(qmp->pd_list->pd_devs[0]); >> + if (ret) >> + return ret; >> + >> + ret = pm_runtime_resume_and_get(qmp->pd_list->pd_devs[1]); >> + if (ret) >> + pm_runtime_put_sync(qmp->pd_list->pd_devs[0]); >> + >> + return ret; >> +} > > [Severity: High] > Does this sequence power up the domains in the wrong order? > > The commit message notes that "usb_core" (which maps to pd_devs[1] based on > the qmp_usb_domain_attach order) controls the GDSC, while "usb_transfer" > (pd_devs[0]) controls clocks and interconnects. > > Enabling clocks before the GDSC foundational power domain is enabled typically > results in unpowered register access on Qualcomm SoCs, which could trigger a > Network-on-Chip (NoC) error and bus hang. Should pd_devs[1] be resumed before > pd_devs[0]? I did not observe any bus errors during my testing. I tried to insert/remove the phy driver and also could detect a flash drive using a couple of more patches on other USB drivers. So I'll keep it this way for v3. > >> + >> +/* d0_to_d3 transition by turning off all the suppliers */ >> +static void qmp_usb_d0_to_d3(struct qmp_usb *qmp) >> +{ >> + if (!qmp->pd_list) >> + return; >> + >> + pm_runtime_put_sync(qmp->pd_list->pd_devs[1]); >> + pm_runtime_put_sync(qmp->pd_list->pd_devs[0]); >> +} > > [Severity: High] > Similarly, could this cause a bus hang during the d0 to d3 transition? > > Putting "usb_core" (pd_devs[1]) before "usb_transfer" (pd_devs[0]) disables > the GDSC before the clocks. Shouldn't the GDSC be disabled last to prevent > unpowered hardware clock access? When running modprobe -r, I did not observe any bus hang on my board. I'll keep this way for v3. > > -- > Sashiko AI review · https://sashiko.dev/#/patchset/20260709-phy-qcom-qmp-usb-8255-v2-0-3b6c26a45788@kernel.org?part=2 ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-07-22 12:18 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-07-09 14:52 [PATCH v2 0/2] Add support for SA8255P in the qcom-qmp-usb phy driver Mattijs Korpershoek 2026-07-09 14:52 ` [PATCH v2 1/2] dt-bindings: phy: qcom,sc8280xp-qmp-usb3-uni: Add SA8255P USB PHY Mattijs Korpershoek 2026-07-11 17:13 ` Krzysztof Kozlowski 2026-07-22 12:18 ` Mattijs Korpershoek 2026-07-09 14:52 ` [PATCH v2 2/2] phy: qcom: qmp-usb: Add support for SA8255P Mattijs Korpershoek 2026-07-09 15:06 ` sashiko-bot 2026-07-22 12:10 ` Mattijs Korpershoek
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox