* Re: [PATCH v3 2/4] dt-bindings: phy: qcom,qcs615-qmp-usb3-dp-phy: Add support for Shikra
From: Krzysztof Kozlowski @ 2026-05-27 9:46 UTC (permalink / raw)
To: Pratham Pratap
Cc: Neil Armstrong, Vinod Koul, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Xiangxu Yin,
Johan Hovold, Loic Poulain, Kathiravan Thirumoorthy,
Dmitry Baryshkov, Abel Vesa, linux-arm-msm, linux-phy, devicetree,
linux-kernel, Krishna Kurapati
In-Reply-To: <20260526184401.3959717-3-pratham.pratap@oss.qualcomm.com>
On Wed, May 27, 2026 at 12:13:59AM +0530, Pratham Pratap wrote:
> From: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
>
> Declare the USB QMP Phy present on Shikra SoC. On this SoC, although
> there are DP registers, the required internal pins have been removed
> and hence DP wouldn't be operational.
>
> Shikra needs 3 resets (dp/ phy/ phy_phy) to be asserted and de-asserted
> as per hardware recommendation. Extend the bindings to accommodate the
> additional reset.
>
> Use QCS615 as a fallback since the software interface is compatible with
> Shikra.
>
> Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
> Signed-off-by: Pratham Pratap <pratham.pratap@oss.qualcomm.com>
> ---
> .../bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml | 13 ++++++++++---
> 1 file changed, 10 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
> index efb465c71c1b..65ae4c6e09db 100644
> --- a/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
> @@ -16,8 +16,12 @@ description:
>
> properties:
> compatible:
> - enum:
> - - qcom,qcs615-qmp-usb3-dp-phy
> + oneOf:
> + - items:
> + - enum:
> + - qcom,shikra-qmp-usb3-dp-phy
> + - const: qcom,qcs615-qmp-usb3-dp-phy
> + - const: qcom,qcs615-qmp-usb3-dp-phy
>
> reg:
> maxItems: 1
> @@ -33,12 +37,15 @@ properties:
> - const: pipe
>
> resets:
> - maxItems: 2
> + minItems: 2
> + maxItems: 3
So QCS615 has three resets now? This needs to be explained in the commit
msg. Or fixed with constraints, see writing bindings.
>
> reset-names:
> + minItems: 2
> items:
> - const: phy_phy
> - const: dp_phy
> + - const: phy
Not phy_phy_phy? Joking aside, you already have a phy - "phy_phy" - so
this is not correct name. I don't know what is the correct name, though.
Please consult device manual.
>
> vdda-phy-supply: true
>
> --
> 2.34.1
>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v3 1/5] dt-bindings: arm: qcom: Document Shikra and its EVK boards
From: Krzysztof Kozlowski @ 2026-05-27 8:55 UTC (permalink / raw)
To: Komal Bajaj
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vinod Koul, Neil Armstrong, Wesley Cheng,
Ulf Hansson, linux-arm-msm, devicetree, linux-kernel, linux-phy,
linux-mmc, monish.chunara
In-Reply-To: <951c9b8f-4513-47ca-afb6-481dedd3eff9@oss.qualcomm.com>
On Wed, May 27, 2026 at 12:42:20PM +0530, Komal Bajaj wrote:
> On 5/26/2026 9:15 PM, Krzysztof Kozlowski wrote:
> > On Fri, May 22, 2026 at 11:32:24PM +0530, Komal Bajaj wrote:
> > > Shikra is a Qualcomm IoT SoC available in a System-on-Module (SoM)
> > > form factor. The SoM integrates the Shikra SoC, PMICs, and essential
> > > passives, and is designed to be mounted on carrier boards.
> > >
> > > Three eSoM variant are introduced:
> > > - CQM: retail variant with integrated modem
> > > - CQS: retail variant without modem
> > > - IQS: industrial-grade variant without modem
> > Industrial/consumer variants differ often only with thermal, so how is
> > it here? Thermal difference does not make them incompatible. Honestly,
> > usually industrial one does not even receive dedicated compatibles.
>
> The IQS variant uses a PM8150 PMIC, while CQS/CQM use PM4125 + PM8005. These
This should be part of commit msg. You explained WHAT you did, not WHY.
We see the diff and we see you added cqm, cqs and iqs...
Also:
Please wrap commit message according to Linux coding style / submission
process (neither too early nor over the limit):
https://elixir.bootlin.com/linux/v6.4-rc1/source/Documentation/process/submitting-patches.rst#L597
Best regards,
Krzysztof
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2] phy: renesas: phy-rzg3e-usb3: Use SYSTEM_SLEEP_PM_OPS instead of NOIRQ
From: sashiko-bot @ 2026-05-27 8:53 UTC (permalink / raw)
To: Ovidiu Panait; +Cc: wsa+renesas, neil.armstrong, olteanv, linux-phy, vkoul
In-Reply-To: <20260527082052.117289-1-ovidiu.panait.rb@renesas.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [High] The driver manually manipulates the runtime PM usage count inside sleep callbacks, which defeats PM core synchronization and causes underflows on error paths.
- [High] Asynchronous pm_runtime_put() is used immediately before asserting a hardware reset, violating hardware ordering constraints and causing race conditions.
- [High] Flawed skip_reinit state machine leaves the PHY uninitialized if it runtime suspends after system resume.
--
commit cdc6f90932d427eedd494d80964982fd1f09abcb
Author: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
phy: renesas: phy-rzg3e-usb3: Use SYSTEM_SLEEP_PM_OPS instead of NOIRQ
This patch moves the suspend/resume callbacks out of the noirq phase by
switching from NOIRQ_SYSTEM_SLEEP_PM_OPS to SYSTEM_SLEEP_PM_OPS. This aims
to fix a PM usage count underflow on suspend when the xhci driver is
unbound.
> diff --git a/drivers/phy/renesas/phy-rzg3e-usb3.c b/drivers/phy/renesas/phy-rzg3e-usb3.c
> index 6b3453ea0004c..7867ca3bc3ab2 100644
> --- a/drivers/phy/renesas/phy-rzg3e-usb3.c
> +++ b/drivers/phy/renesas/phy-rzg3e-usb3.c
> @@ -235,7 +235,7 @@ static int rzg3e_phy_usb3_resume(struct device *dev)
> }
>
> static const struct dev_pm_ops rzg3e_phy_usb3_pm = {
> - NOIRQ_SYSTEM_SLEEP_PM_OPS(rzg3e_phy_usb3_suspend, rzg3e_phy_usb3_resume)
> + SYSTEM_SLEEP_PM_OPS(rzg3e_phy_usb3_suspend, rzg3e_phy_usb3_resume)
> };
[Severity: High]
This isn't a bug introduced by this patch, but modifying these callbacks
brings up a preexisting issue. Does the manual manipulation of runtime PM
usage counts inside these sleep callbacks defeat the PM core's
synchronization?
The PM core takes a runtime PM reference on all devices during
device_prepare() to prevent concurrent transitions during system sleep, and
releases it in device_complete().
If rzg3e_phy_usb3_suspend() manually drops this reference, and
rzg3e_phy_usb3_resume() attempts to reacquire it but fails early on an error
path:
static int rzg3e_phy_usb3_resume(struct device *dev)
{
...
ret = reset_control_deassert(r->rstc);
if (ret)
return ret;
ret = pm_runtime_resume_and_get(dev);
...
Will this cause another negative usage count underflow when the PM core
unconditionally calls device_complete() and executes its own
pm_runtime_put()?
[Severity: High]
This is a pre-existing issue, but does the suspend path introduce a race
condition by using an asynchronous runtime put just before asserting the
hardware reset?
In rzg3e_phy_usb3_suspend(), the driver drops the runtime PM reference via
pm_runtime_put() and then immediately asserts the hardware reset line.
Because pm_runtime_put() is asynchronous, could the generic PM domain be
powered off concurrently with or immediately after the hardware reset is
synchronously asserted?
[Severity: High]
This is a pre-existing issue, but does the skip_reinit state machine leave
the PHY uninitialized if it runtime suspends after system resume?
During system resume, rzg3e_phy_usb3_resume() unconditionally sets
r->skip_reinit = true. This flag is only cleared during system suspend.
If the PHY consumer unbinds or runtime suspends, the PHY loses its hardware
state. When the consumer is later bound or runtime resumed, it calls
phy_init() to reinitialize. Since r->skip_reinit is still true, will
phy_init() skip the initialization sequence and leave the hardware broken
until the next full system suspend cycle?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260527082052.117289-1-ovidiu.panait.rb@renesas.com?part=1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v2] phy: renesas: phy-rzg3e-usb3: Use SYSTEM_SLEEP_PM_OPS instead of NOIRQ
From: Ovidiu Panait @ 2026-05-27 8:20 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Biju Das, Geert Uytterhoeven
Cc: linux-phy, linux-kernel, linux-renesas-soc, Ovidiu Panait
On the Renesas RZ/V2H platform, if the xhci driver is unbound and the
system is suspended afterwards, a PM underflow error will occur:
# echo 15850000.usb > /sys/bus/platform/drivers/xhci-renesas-hcd/unbind
# systemctl suspend
15870000.usb-phy: PM: dpm_run_callback(): genpd_resume_noirq returns -13
15870000.usb-phy: PM: failed to resume noirq: error -13
15870000.usb-phy: Runtime PM usage count underflow!
When the xhci driver is unbound, the runtime PM usage count of the PHY
drops to 0. Since the suspend/resume callbacks are in the noirq phase,
the pm_runtime_resume_and_get() on resume errors out with -EACCES and
the usage count stays at 0. The subsequent put in device_complete()
then underflows the counter.
To fix this, move the suspend/resume callbacks out of the noirq phase by
switching from NOIRQ_SYSTEM_SLEEP_PM_OPS to SYSTEM_SLEEP_PM_OPS.
Fixes: ee5f1a3f90a4 ("phy: renesas: Add Renesas RZ/G3E USB3.0 PHY driver")
Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
---
v2:
- Dropped the runtime PM rework part from the previous version, as it
was not needed to fix the original issue.
v1: https://lore.kernel.org/all/20260427194741.161533-1-ovidiu.panait.rb@renesas.com/
drivers/phy/renesas/phy-rzg3e-usb3.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/phy/renesas/phy-rzg3e-usb3.c b/drivers/phy/renesas/phy-rzg3e-usb3.c
index 060309547ea5..4d2b0f5f5b09 100644
--- a/drivers/phy/renesas/phy-rzg3e-usb3.c
+++ b/drivers/phy/renesas/phy-rzg3e-usb3.c
@@ -233,7 +233,7 @@ static int rzg3e_phy_usb3_resume(struct device *dev)
}
static const struct dev_pm_ops rzg3e_phy_usb3_pm = {
- NOIRQ_SYSTEM_SLEEP_PM_OPS(rzg3e_phy_usb3_suspend, rzg3e_phy_usb3_resume)
+ SYSTEM_SLEEP_PM_OPS(rzg3e_phy_usb3_suspend, rzg3e_phy_usb3_resume)
};
static const struct of_device_id rzg3e_phy_usb3_match_table[] = {
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* Re: [PATCH v3 1/5] dt-bindings: arm: qcom: Document Shikra and its EVK boards
From: Komal Bajaj @ 2026-05-27 7:12 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vinod Koul, Neil Armstrong, Wesley Cheng,
Ulf Hansson, linux-arm-msm, devicetree, linux-kernel, linux-phy,
linux-mmc, monish.chunara
In-Reply-To: <20260526-quantum-funny-gorilla-cfc983@quoll>
On 5/26/2026 9:15 PM, Krzysztof Kozlowski wrote:
> On Fri, May 22, 2026 at 11:32:24PM +0530, Komal Bajaj wrote:
>> Shikra is a Qualcomm IoT SoC available in a System-on-Module (SoM)
>> form factor. The SoM integrates the Shikra SoC, PMICs, and essential
>> passives, and is designed to be mounted on carrier boards.
>>
>> Three eSoM variant are introduced:
>> - CQM: retail variant with integrated modem
>> - CQS: retail variant without modem
>> - IQS: industrial-grade variant without modem
> Industrial/consumer variants differ often only with thermal, so how is
> it here? Thermal difference does not make them incompatible. Honestly,
> usually industrial one does not even receive dedicated compatibles.
The IQS variant uses a PM8150 PMIC, while CQS/CQM use PM4125 + PM8005.
These have different regulator topologies and RPM regulator bindings,
making the DTBs genuinely incompatible, IQS SoM cannot boot with CQS
DTB. Thus, a separate compatible is required and not merely a thermal
distinction.
Thanks
Komal
> Best regards,
> Krzysztof
>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v3 4/4] phy: qcom: qmp-usbc: Add support for "phy" reset used on Shikra
From: Xiangxu Yin @ 2026-05-27 6:27 UTC (permalink / raw)
To: Pratham Pratap, Neil Armstrong, Vinod Koul, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
Johan Hovold, Loic Poulain, Kathiravan Thirumoorthy,
Dmitry Baryshkov, Abel Vesa
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Krishna Kurapati
In-Reply-To: <20260526184401.3959717-5-pratham.pratap@oss.qualcomm.com>
On 5/27/2026 2:44 AM, Pratham Pratap wrote:
> From: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
>
> Shikra uses three resets (dp/ phy/ phy_phy). Add the extra "phy" reset
> needed for operation of QMP Phy on Shikra.
>
> Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
> Signed-off-by: Pratham Pratap <pratham.pratap@oss.qualcomm.com>
> ---
> drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> index c342479a3798..067e7f6e5642 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> @@ -513,7 +513,7 @@ static const char * const usb3phy_reset_l[] = {
> };
>
> static const char * const usb3dpphy_reset_l[] = {
> - "phy_phy", "dp_phy",
> + "phy_phy", "dp_phy", "phy",
> };
>
usb3dpphy_reset_l is shared with qcs615_usb3dp_phy_cfg, but I didn't find any optional-reset handling in qmp_usbc_reset_init().
talos.dtsi only defines two resets for qcom,qcs615-qmp-usb3-dp-phy, so adding "phy" here unconditionally will break probe on QCS615.
Please create a separate reset list for Shikra instead.
> static const struct regulator_bulk_data qmp_phy_msm8998_vreg_l[] = {
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH net-next v8] net: phy: sfp: probe for RollBall I2C-to-MDIO bridge in mdio-i2c
From: Petr Wozniak @ 2026-05-27 5:39 UTC (permalink / raw)
To: netdev
Cc: maxime.chevallier, bjorn, andrew, hkallweit1, linux, davem,
edumazet, kuba, pabeni, linux-phy, linux-kernel, jan,
Petr Wozniak
The "OEM"/"SFP-10G-T" quirk entry in sfp_fixup_rollball_cc()
unconditionally forces MDIO_I2C_ROLLBALL for all modules matching that
vendor/part-number combination. This works for modules that genuinely
implement a RollBall I2C-to-MDIO bridge, but silently breaks modules
that share the same EEPROM strings without having such a bridge.
The Realtek RTL8261BE-CG is one such module: a pure copper 10G SFP+
media converter with no I2C-to-MDIO bridge. Its EEPROM reports
vendor="OEM", part="SFP-10G-T-I", and -- critically -- Vendor OUI
00:00:00, making OUI-based differentiation impossible. With
MDIO_I2C_ROLLBALL forced, the module silently ACKs the unlock password
write, the MDIO bus is created, but no PHY responds; the SFP state
machine cycles through the RollBall PHY-probe retry window before
reporting no PHY.
Move the probe into i2c_mii_init_rollball() in mdio-i2c.c, where the
RollBall protocol constants are already defined. After sending the
unlock password, issue a CMD_READ and poll for CMD_DONE up to 200 ms
(10 x 20 ms, matching the existing rollball poll tolerance). A genuine
RollBall bridge asserts CMD_DONE within that window; modules without a
bridge never do, so i2c_mii_init_rollball() returns -ENODEV.
mdio_i2c_alloc() propagates -ENODEV to the caller to signal that no
bridge is present and PHY probing should be skipped.
sfp_sm_add_mdio_bus() catches -ENODEV and transitions
sfp->mdio_protocol to MDIO_I2C_NONE so the rest of the state machine
skips PHY probing for this module.
Any I2C-level error (NACK, timeout) during the probe is also treated as
-ENODEV: if the module does not respond at I2C address 0x51 at all,
there is certainly no RollBall bridge there, and SFP initialization
should not abort.
The probe writes are safe with respect to SFP EEPROM integrity: only
modules explicitly listed in the quirk table enter this path, and the
RollBall password unlock write to 0x51 was already issued by
i2c_mii_init_rollball() before the probe for all such modules. Any
module without a device at 0x51 NACKs the transfer and is treated as
-ENODEV.
Add "OEM"/"SFP-10G-T-I" to the quirk table so RTL8261BE modules enter
the probe path; genuine RollBall modules continue to work as before.
Signed-off-by: Petr Wozniak <petr.wozniak@gmail.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
Changes since v7 (feedback from Jakub Kicinski):
- Rebased on current net-next; no functional changes
Changes since v6 (feedback from Maxime Chevallier):
- Remove redundant if (ret) checks after i2c_transfer_rollball() calls;
the function never returns a positive value (always 0 or negative),
so these branches were dead code
Changes since v5 (Sashiko AI review):
- Treat I2C NACK/errors in i2c_mii_init_rollball() as -ENODEV so
modules without a 0x51 EEPROM do not abort SFP initialization
- Replace fixed 70 ms wait with 10 x 20 ms poll (total 200 ms),
matching the existing i2c_rollball_mii_poll() tolerance and
preventing false -ENODEV on slow RollBall bridges
Changes since v4 (feedback from Maxime Chevallier):
- Fix commit message: replace "stalls" with accurate description of
the RollBall PHY-probe retry window
- Fix variable declaration order in i2c_mii_probe_rollball() to
follow reverse-xmas tree (descending line length)
- Remove spurious alignment space on "SFP-10G-T" quirk entry
- Document that -ENODEV from mdio_i2c_alloc() means no bridge present,
PHY probing should be skipped
Changes since v3 (feedback from Jakub Kicinski):
- Drop spurious Tested-by: tag -- author and tester are the same person
- Use PATCH net-next subject prefix
- Move -ENODEV handling from sfp_i2c_mdiobus_create() into
sfp_sm_add_mdio_bus() so bus-creation code does not mutate
sfp->mdio_protocol; the state machine is the correct place for
protocol-state transitions
- Split combined variable declaration for clarity
Changes since v2:
- Compile-tested and hardware-tested on BPI-R4 (MT7988A, 6.12.87)
- RTL8261BE (OEM/SFP-10G-T-I): probes MDIO_I2C_NONE, link Up 10Gbps
- Genuine RollBall (OEM/SFP-10G-T): bridge detected, link Up 10Gbps
---
drivers/net/mdio/mdio-i2c.c | 59 ++++++++++++++++++++++++++++++++-----
drivers/net/phy/sfp.c | 14 +++++++--
2 files changed, 63 insertions(+), 10 deletions(-)
diff --git a/drivers/net/mdio/mdio-i2c.c b/drivers/net/mdio/mdio-i2c.c
index ed20352a5..b88f63234 100644
--- a/drivers/net/mdio/mdio-i2c.c
+++ b/drivers/net/mdio/mdio-i2c.c
@@ -419,6 +419,50 @@ static int i2c_mii_write_rollball(struct mii_bus *bus, int phy_id, int devad,
return 0;
}
+static int i2c_mii_probe_rollball(struct i2c_adapter *i2c)
+{
+ u8 data_buf[] = { ROLLBALL_DATA_ADDR, 0x01, 0x00, 0x00 };
+ u8 cmd_buf[] = { ROLLBALL_CMD_ADDR, ROLLBALL_CMD_READ };
+ u8 cmd_addr = ROLLBALL_CMD_ADDR;
+ struct i2c_msg msgs[2];
+ u8 result;
+ int ret;
+ int i;
+
+ msgs[0].addr = ROLLBALL_PHY_I2C_ADDR;
+ msgs[0].flags = 0;
+ msgs[0].len = sizeof(data_buf);
+ msgs[0].buf = data_buf;
+ msgs[1].addr = ROLLBALL_PHY_I2C_ADDR;
+ msgs[1].flags = 0;
+ msgs[1].len = sizeof(cmd_buf);
+ msgs[1].buf = cmd_buf;
+
+ ret = i2c_transfer_rollball(i2c, msgs, ARRAY_SIZE(msgs));
+ if (ret < 0)
+ return -ENODEV;
+
+ msgs[0].addr = ROLLBALL_PHY_I2C_ADDR;
+ msgs[0].flags = 0;
+ msgs[0].len = 1;
+ msgs[0].buf = &cmd_addr;
+ msgs[1].addr = ROLLBALL_PHY_I2C_ADDR;
+ msgs[1].flags = I2C_M_RD;
+ msgs[1].len = 1;
+ msgs[1].buf = &result;
+
+ for (i = 0; i < 10; i++) {
+ msleep(20);
+ ret = i2c_transfer_rollball(i2c, msgs, ARRAY_SIZE(msgs));
+ if (ret < 0)
+ return -ENODEV;
+ if (result == ROLLBALL_CMD_DONE)
+ return 0;
+ }
+
+ return -ENODEV;
+}
+
static int i2c_mii_init_rollball(struct i2c_adapter *i2c)
{
struct i2c_msg msg;
@@ -438,11 +482,11 @@ static int i2c_mii_init_rollball(struct i2c_adapter *i2c)
ret = i2c_transfer(i2c, &msg, 1);
if (ret < 0)
- return ret;
- else if (ret != 1)
+ return -ENODEV;
+ if (ret != 1)
return -EIO;
- else
- return 0;
+
+ return i2c_mii_probe_rollball(i2c);
}
static bool mdio_i2c_check_functionality(struct i2c_adapter *i2c,
@@ -487,9 +531,10 @@ struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c,
case MDIO_I2C_ROLLBALL:
ret = i2c_mii_init_rollball(i2c);
if (ret < 0) {
- dev_err(parent,
- "Cannot initialize RollBall MDIO I2C protocol: %d\n",
- ret);
+ if (ret != -ENODEV)
+ dev_err(parent,
+ "Cannot initialize RollBall MDIO I2C protocol: %d\n",
+ ret);
mdiobus_free(mii);
return ERR_PTR(ret);
}
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index bd970f753..7b2c20d78 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -579,6 +579,7 @@ static const struct sfp_quirk sfp_quirks[] = {
// OEM SFP-GE-T is a 1000Base-T module with broken TX_FAULT indicator
SFP_QUIRK_F("OEM", "SFP-GE-T", sfp_fixup_ignore_tx_fault),
+ SFP_QUIRK_F("OEM", "SFP-10G-T-I", sfp_fixup_rollball),
SFP_QUIRK_F("OEM", "SFP-10G-T", sfp_fixup_rollball_cc),
SFP_QUIRK_S("OEM", "SFP-2.5G-T", sfp_quirk_oem_2_5g),
SFP_QUIRK_S("OEM", "SFP-2.5G-BX10-D", sfp_quirk_2500basex),
@@ -2022,10 +2023,17 @@ static void sfp_sm_fault(struct sfp *sfp, unsigned int next_state, bool warn)
static int sfp_sm_add_mdio_bus(struct sfp *sfp)
{
- if (sfp->mdio_protocol != MDIO_I2C_NONE)
- return sfp_i2c_mdiobus_create(sfp);
+ int ret;
- return 0;
+ if (sfp->mdio_protocol == MDIO_I2C_NONE)
+ return 0;
+
+ ret = sfp_i2c_mdiobus_create(sfp);
+ if (ret == -ENODEV) {
+ sfp->mdio_protocol = MDIO_I2C_NONE;
+ return 0;
+ }
+ return ret;
}
/* Probe a SFP for a PHY device if the module supports copper - the PHY
--
2.51.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* Re: [PATCH net-next v7] net: phy: sfp: probe for RollBall I2C-to-MDIO bridge in mdio-i2c
From: Jakub Kicinski @ 2026-05-27 0:59 UTC (permalink / raw)
To: Petr Wozniak
Cc: netdev, maxime.chevallier, bjorn, andrew, hkallweit1, linux,
davem, edumazet, pabeni, linux-phy, linux-kernel, jan
In-Reply-To: <20260523151859.1665-1-petr.wozniak@gmail.com>
On Sat, 23 May 2026 17:18:59 +0200 Petr Wozniak wrote:
> Subject: [PATCH net-next v7] net: phy: sfp: probe for RollBall I2C-to-MDIO bridge in mdio-i2c
Still does not apply on net-next:
https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/
--
pw-bot: cr
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v3 4/4] phy: qcom: qmp-usbc: Add support for "phy" reset used on Shikra
From: sashiko-bot @ 2026-05-26 19:52 UTC (permalink / raw)
To: Pratham Pratap
Cc: olteanv, linux-phy, devicetree, vkoul, robh, conor+dt,
neil.armstrong
In-Reply-To: <20260526184401.3959717-5-pratham.pratap@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Critical] Unconditionally adding the 'phy' reset to `usb3dpphy_reset_l` breaks the driver probe for existing QCS615 platforms.
--
commit c8024a0d34e805ada6e128fcb57e931ef7692038
Author: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
phy: qcom: qmp-usbc: Add support for "phy" reset used on Shikra
This patch adds the "phy" reset to the usb3dpphy_reset_l array. This extra
reset is needed for the operation of the QMP Phy on the Shikra platform.
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> index c342479a37980..067e7f6e56424 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
[ ... ]
> static const char * const usb3dpphy_reset_l[] = {
> - "phy_phy", "dp_phy",
> + "phy_phy", "dp_phy", "phy",
[Severity: Critical]
Will adding this reset unconditionally cause a probe failure for existing
QCS615 platforms?
The length of the usb3dpphy_reset_l array is used by ARRAY_SIZE() to define
the num_resets value for the configuration. Since qmp_usbc_reset_init()
fetches these resets using devm_reset_control_bulk_get_exclusive(), it
strictly requires all requested resets to be present in the device tree.
If an older device tree only defines the two original resets, phy_phy and
dp_phy, won't the driver fail to find the third reset and return -ENOENT,
causing the probe to abort?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260526184401.3959717-1-pratham.pratap@oss.qualcomm.com?part=4
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v3 2/4] dt-bindings: phy: qcom,qcs615-qmp-usb3-dp-phy: Add support for Shikra
From: sashiko-bot @ 2026-05-26 19:13 UTC (permalink / raw)
To: Pratham Pratap
Cc: linux-phy, vkoul, conor+dt, olteanv, robh, devicetree,
neil.armstrong
In-Reply-To: <20260526184401.3959717-3-pratham.pratap@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] QCS615 is an invalid fallback for Shikra due to differing hardware reset requirements and removed DisplayPort functionality.
- [Medium] Missing `allOf` conditional blocks to enforce correct reset counts for each SoC variant.
--
commit fb0664de6e00aa81793b7c92908a732069771e68
Author: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
dt-bindings: phy: qcom,qcs615-qmp-usb3-dp-phy: Add support for Shikra
This commit extends the QCS615 QMP USB3/DP PHY bindings to add support for
the Shikra SoC. It introduces a new compatible string with QCS615 as a
fallback, and increases the maximum number of resets to accommodate Shikra.
> Declare the USB QMP Phy present on Shikra SoC. On this SoC, although
> there are DP registers, the required internal pins have been removed
> and hence DP wouldn't be operational.
>
> Shikra needs 3 resets (dp/ phy/ phy_phy) to be asserted and de-asserted
> as per hardware recommendation. Extend the bindings to accommodate the
> additional reset.
>
> Use QCS615 as a fallback since the software interface is compatible with
> Shikra.
[Severity: High]
Is QCS615 a valid fallback for the Shikra SoC here?
The commit message notes that Shikra requires an additional third reset
(phy) per hardware recommendations, and that DisplayPort functionality is
non-operational. If an older kernel matches the Shikra device using the
QCS615 fallback driver, it will fail to assert the required third reset and
will erroneously attempt to initialize the physically disconnected DP
functionality.
Could this lead to incomplete hardware initialization and potential
subsystem timeouts?
> diff --git a/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
> index efb465c71c1b5..65ae4c6e09db0 100644
> --- a/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
[ ... ]
> @@ -33,12 +37,15 @@ properties:
> - const: pipe
>
> resets:
> - maxItems: 2
> + minItems: 2
> + maxItems: 3
>
> reset-names:
> + minItems: 2
> items:
> - const: phy_phy
> - const: dp_phy
> + - const: phy
[Severity: Medium]
Will this allow invalid device tree configurations to silently pass schema
validation?
By relaxing the global constraints to allow up to 3 resets, a QCS615 node
could incorrectly specify 3 resets, or a Shikra node could incorrectly
specify only 2.
Should we add an allOf section with if-then conditional blocks to enforce
the exact required counts for each SoC variant (exactly 2 for QCS615, and
exactly 3 for Shikra)?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260526184401.3959717-1-pratham.pratap@oss.qualcomm.com?part=2
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2] phy: renesas: rcar-gen3-usb2: Avoid long delay in atomic context
From: sashiko-bot @ 2026-05-26 18:58 UTC (permalink / raw)
To: Claudiu Beznea; +Cc: wsa+renesas, neil.armstrong, olteanv, linux-phy, vkoul
In-Reply-To: <20260526183045.3887660-1-claudiu.beznea@kernel.org>
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] The `role_store` function returns incorrect values (-EIO on success, or `count` on failure) due to improperly repurposing the `ret` variable.
- [High] Early returns on timeout in `power_on`, `power_off`, and `exit` bypass critical teardown, leaving resources leaked.
- [High] The top-level common interrupt enable (`UCOM_INTEN`) is left active during the 20ms sleep, which can lead to an unhandled IRQ storm.
- [Medium] The 30ms timeout for `wait_for_completion_timeout()` is far too tight compared to the 20ms `fsleep()`, leading to highly probable spurious timeouts.
- [Medium] Mixing `goto`-based error handling and `scoped_guard()` cleanup within the same function.
--
commit 3dc5ff3b13d78d4a92dd7b7c9e196a323d152a48
Author: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Subject: phy: renesas: rcar-gen3-usb2: Avoid long delay in atomic context
This commit addresses a long delay in atomic context by releasing the spin
lock, sleeping for 20 ms, and using a completion and state flag to handle
concurrent configuration requests.
Link: https://lore.kernel.org/all/afhkX2Ys2BG1gnqy@duo.ucw.cz
Link: https://lore.kernel.org/all/afhkX2Ys2BG1gnqy@duo.ucw.cz
> diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> index 79e820e2fe55d..4379ea044135a 100644
> --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
> +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
[ ... ]
> @@ -394,26 +402,48 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr,
> struct rcar_gen3_chan *ch = dev_get_drvdata(dev);
> bool is_b_device;
> enum phy_mode cur_mode, new_mode;
> + unsigned long flags;
> + int ret = -EIO;
>
> - guard(spinlock_irqsave)(&ch->lock);
> + spin_lock_irqsave(&ch->lock, flags);
>
> - if (!ch->is_otg_channel || !rcar_gen3_is_any_otg_rphy_initialized(ch))
> - return -EIO;
> + if (!ch->is_otg_channel)
> + goto unlock;
> +
> + if (ch->otg_initializing) {
> + unsigned long timeout = msecs_to_jiffies(30);
> +
> + spin_unlock_irqrestore(&ch->lock, flags);
> +
> + ret = wait_for_completion_timeout(&ch->otg_init_done, timeout);
> + ret = ret ? 0 : -ETIMEDOUT;
> + if (ret)
> + return ret;
> +
> + spin_lock_irqsave(&ch->lock, flags);
> + }
[ ... ]
> - return count;
> +unlock:
> + spin_unlock_irqrestore(&ch->lock, flags);
> +
> + return ret ?: count;
> }
[Severity: High]
Is the logic for the return value here inverted? The ret variable starts as
-EIO and is never reassigned on the success path, meaning role_store will
return -EIO on success. Conversely, if wait_for_completion_timeout fails,
ret becomes 0, so the function will incorrectly return count on failure.
[ ... ]
> @@ -512,6 +546,11 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
> goto rpm_put;
>
> scoped_guard(spinlock, &ch->lock) {
> + if (ch->otg_initializing) {
> + ret = IRQ_NONE;
> + goto rpm_put;
> + }
> +
[Severity: Medium]
Is it intentional to mix goto statements with scoped_guard() within this
function? The subsystem guidelines typically prefer either scope-based cleanup
or goto-based cleanup, but mixing them in the same routine is discouraged.
[ ... ]
> +static void rcar_gen3_phy_usb2_irqs_mask_all(struct rcar_gen3_chan *channel,
> + u32 *masked_irqs_bits)
> +{
> + void __iomem *usb2_base = channel->base;
> + u32 val, bitmask = 0;
> +
> + for (unsigned int i = 0; i < NUM_OF_PHYS; i++)
> + bitmask |= channel->rphys[i].int_enable_bits;
> +
> + val = readl(usb2_base + USB2_INT_ENABLE);
> + *masked_irqs_bits = val & bitmask;
> + val &= ~bitmask;
> + writel(val, usb2_base + USB2_INT_ENABLE);
> +}
[Severity: High]
Does this adequately mask the top-level common interrupt enable (UCOM_INTEN)?
If an interrupt fires during the 20ms sleep phase, and the handler exits early
with IRQ_NONE when otg_initializing is true, could this cause an unhandled
IRQ storm without clearing the hardware status?
[ ... ]
> @@ -550,8 +634,24 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
> }
>
> /* Initialize otg part (only if we initialize a PHY with IRQs). */
> - if (rphy->int_enable_bits)
> - rcar_gen3_init_otg(channel);
> + if (rphy->int_enable_bits && channel->is_otg_channel &&
> + !rcar_gen3_is_any_otg_rphy_initialized(channel)) {
> + u32 masked_irq_bits = 0;
> +
> + rcar_gen3_init_otg_phase0(channel);
> + rcar_gen3_phy_usb2_irqs_mask_all(channel, &masked_irq_bits);
> + reinit_completion(&channel->otg_init_done);
> + channel->otg_initializing = true;
> + spin_unlock_irqrestore(&channel->lock, flags);
> +
> + fsleep(20000);
> +
> + spin_lock_irqsave(&channel->lock, flags);
> + channel->otg_initializing = false;
> + complete_all(&channel->otg_init_done);
[Severity: Medium]
Is a 30ms timeout for wait_for_completion_timeout() sufficient across
accessing functions? Considering the background initialization uses
fsleep(20000), which can natively span up to 30ms depending on jiffy
granularity and scheduling jitter, could this result in spurious timeouts?
[ ... ]
> @@ -607,7 +726,20 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p)
> return ret;
> }
>
> - guard(spinlock_irqsave)(&channel->lock);
> + spin_lock_irqsave(&channel->lock, flags);
> +
> + if (channel->otg_initializing) {
> + unsigned long timeout = msecs_to_jiffies(30);
> +
> + spin_unlock_irqrestore(&channel->lock, flags);
> +
> + ret = wait_for_completion_timeout(&channel->otg_init_done, timeout);
> + ret = ret ? 0 : -ETIMEDOUT;
> + if (ret)
> + return ret;
> +
> + spin_lock_irqsave(&channel->lock, flags);
> + }
[Severity: High]
Does returning early on timeout bypass the regulator_disable() teardown
at the end of the function, potentially causing a regulator leak? The same
pattern appears to apply to power_off and exit if they rely on final teardown
blocks that this early return avoids.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260526183045.3887660-1-claudiu.beznea@kernel.org?part=1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v3 4/4] phy: qcom: qmp-usbc: Add support for "phy" reset used on Shikra
From: Pratham Pratap @ 2026-05-26 18:44 UTC (permalink / raw)
To: Neil Armstrong, Vinod Koul, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Xiangxu Yin,
Johan Hovold, Loic Poulain, Kathiravan Thirumoorthy,
Dmitry Baryshkov, Abel Vesa
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Krishna Kurapati, Pratham Pratap
In-Reply-To: <20260526184401.3959717-1-pratham.pratap@oss.qualcomm.com>
From: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
Shikra uses three resets (dp/ phy/ phy_phy). Add the extra "phy" reset
needed for operation of QMP Phy on Shikra.
Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
Signed-off-by: Pratham Pratap <pratham.pratap@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index c342479a3798..067e7f6e5642 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -513,7 +513,7 @@ static const char * const usb3phy_reset_l[] = {
};
static const char * const usb3dpphy_reset_l[] = {
- "phy_phy", "dp_phy",
+ "phy_phy", "dp_phy", "phy",
};
static const struct regulator_bulk_data qmp_phy_msm8998_vreg_l[] = {
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v3 3/4] phy: qcom-qusb2: Add support for Shikra
From: Pratham Pratap @ 2026-05-26 18:44 UTC (permalink / raw)
To: Neil Armstrong, Vinod Koul, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Xiangxu Yin,
Johan Hovold, Loic Poulain, Kathiravan Thirumoorthy,
Dmitry Baryshkov, Abel Vesa
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Krishna Kurapati, Pratham Pratap
In-Reply-To: <20260526184401.3959717-1-pratham.pratap@oss.qualcomm.com>
From: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
Add init sequence and phy configuration for Shikra.
Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
Signed-off-by: Pratham Pratap <pratham.pratap@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qusb2.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index eb93015be841..ab7437e7b751 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -381,6 +381,19 @@ static const struct qusb2_phy_cfg sdm660_phy_cfg = {
.autoresume_en = BIT(3),
};
+static const struct qusb2_phy_cfg shikra_phy_cfg = {
+ .tbl = qcs615_init_tbl,
+ .tbl_num = ARRAY_SIZE(qcs615_init_tbl),
+ .regs = ipq6018_regs_layout,
+
+ .has_pll_test = true,
+ .se_clk_scheme_default = true,
+ .disable_ctrl = CLAMP_N_EN | FREEZIO_N | POWER_DOWN,
+ .mask_core_ready = PLL_LOCKED,
+ .autoresume_en = BIT(3),
+ .update_tune1_with_efuse = false,
+};
+
static const struct qusb2_phy_cfg sm6115_phy_cfg = {
.tbl = sm6115_init_tbl,
.tbl_num = ARRAY_SIZE(sm6115_init_tbl),
@@ -958,6 +971,9 @@ static const struct of_device_id qusb2_phy_of_match_table[] = {
}, {
.compatible = "qcom,sdm660-qusb2-phy",
.data = &sdm660_phy_cfg,
+ }, {
+ .compatible = "qcom,shikra-qusb2-phy",
+ .data = &shikra_phy_cfg,
}, {
.compatible = "qcom,sm4250-qusb2-phy",
.data = &sm6115_phy_cfg,
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v3 2/4] dt-bindings: phy: qcom,qcs615-qmp-usb3-dp-phy: Add support for Shikra
From: Pratham Pratap @ 2026-05-26 18:43 UTC (permalink / raw)
To: Neil Armstrong, Vinod Koul, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Xiangxu Yin,
Johan Hovold, Loic Poulain, Kathiravan Thirumoorthy,
Dmitry Baryshkov, Abel Vesa
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Krishna Kurapati, Pratham Pratap
In-Reply-To: <20260526184401.3959717-1-pratham.pratap@oss.qualcomm.com>
From: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
Declare the USB QMP Phy present on Shikra SoC. On this SoC, although
there are DP registers, the required internal pins have been removed
and hence DP wouldn't be operational.
Shikra needs 3 resets (dp/ phy/ phy_phy) to be asserted and de-asserted
as per hardware recommendation. Extend the bindings to accommodate the
additional reset.
Use QCS615 as a fallback since the software interface is compatible with
Shikra.
Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
Signed-off-by: Pratham Pratap <pratham.pratap@oss.qualcomm.com>
---
.../bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
index efb465c71c1b..65ae4c6e09db 100644
--- a/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml
@@ -16,8 +16,12 @@ description:
properties:
compatible:
- enum:
- - qcom,qcs615-qmp-usb3-dp-phy
+ oneOf:
+ - items:
+ - enum:
+ - qcom,shikra-qmp-usb3-dp-phy
+ - const: qcom,qcs615-qmp-usb3-dp-phy
+ - const: qcom,qcs615-qmp-usb3-dp-phy
reg:
maxItems: 1
@@ -33,12 +37,15 @@ properties:
- const: pipe
resets:
- maxItems: 2
+ minItems: 2
+ maxItems: 3
reset-names:
+ minItems: 2
items:
- const: phy_phy
- const: dp_phy
+ - const: phy
vdda-phy-supply: true
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v3 1/4] dt-bindings: phy: qcom,qusb2: Document QUSB2 Phy for Shikra
From: Pratham Pratap @ 2026-05-26 18:43 UTC (permalink / raw)
To: Neil Armstrong, Vinod Koul, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Xiangxu Yin,
Johan Hovold, Loic Poulain, Kathiravan Thirumoorthy,
Dmitry Baryshkov, Abel Vesa
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Krishna Kurapati, Krzysztof Kozlowski, Pratham Pratap
In-Reply-To: <20260526184401.3959717-1-pratham.pratap@oss.qualcomm.com>
From: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
Update dt-bindings to add Shikra to QUSB2 Phy list. Shikra SoC
has two High Speed QUSB2 Phys.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
Signed-off-by: Pratham Pratap <pratham.pratap@oss.qualcomm.com>
---
Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml
index 39851ba9de43..ddbddeec6fb1 100644
--- a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml
@@ -28,6 +28,7 @@ properties:
- qcom,qcm2290-qusb2-phy
- qcom,qcs615-qusb2-phy
- qcom,sdm660-qusb2-phy
+ - qcom,shikra-qusb2-phy
- qcom,sm4250-qusb2-phy
- qcom,sm6115-qusb2-phy
- items:
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v3 0/4] Add USB Phy driver and binding changes for Qualcomm Shikra SoC
From: Pratham Pratap @ 2026-05-26 18:43 UTC (permalink / raw)
To: Neil Armstrong, Vinod Koul, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Xiangxu Yin,
Johan Hovold, Loic Poulain, Kathiravan Thirumoorthy,
Dmitry Baryshkov, Abel Vesa
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Pratham Pratap
This series adds Driver and binding changes for USB Phys on Shikra.
There are two USB controllers - One of them is SS capable and other is
highspeed only capable.
Changes in v3:
- Moved to using qcs615-usb3-dp-phy since the DP Phy is present although
not operational.
- Using Talos as a fallback for shikra in qmp driver
- Add required "phy" reset in qmp usbc driver since its needed on Shikra
Link to v2:
https://lore.kernel.org/all/20260504170659.282532-1-krishna.kurapati@oss.qualcomm.com/
Changes in v2:
- Separated the usb controller binding changes
- Updated commit texts.
Link to v1:
https://lore.kernel.org/all/20260430-shikra-usb-v1-0-c9c108536fdc@oss.qualcomm.com/
Krishna Kurapati (4):
dt-bindings: phy: qcom,qusb2: Document QUSB2 Phy for Shikra
dt-bindings: phy: qcom,qcs615-qmp-usb3-dp-phy: Add support for Shikra
phy: qcom-qusb2: Add support for Shikra
phy: qcom: qmp-usbc: Add support for "phy" reset used on Shikra
.../bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml | 13 ++++++++++---
.../devicetree/bindings/phy/qcom,qusb2-phy.yaml | 1 +
drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 2 +-
drivers/phy/qualcomm/phy-qcom-qusb2.c | 16 ++++++++++++++++
4 files changed, 28 insertions(+), 4 deletions(-)
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v2] phy: renesas: rcar-gen3-usb2: Avoid long delay in atomic context
From: Claudiu Beznea @ 2026-05-26 18:30 UTC (permalink / raw)
To: yoshihiro.shimoda.uh, vkoul, neil.armstrong, geert+renesas,
magnus.damm, prabhakar.mahadev-lad.rj
Cc: claudiu.beznea, claudiu.beznea, linux-renesas-soc, linux-phy,
linux-kernel, Claudiu Beznea, stable, Pavel Machek,
Nobuhiro Iwamatsu
From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
The OTG PHY initialization sequence needs to wait for 20 ms at a specific
step, as described in commit 72c0339c115b ("phy: renesas:
rcar-gen3-usb2: follow the hardware manual procedure").
Commit 55a387ebb921 ("phy: renesas: rcar-gen3-usb2: Lock around hardware
registers and driver data") tried to address various problems in the
rcar-gen3-usb2 driver and converted the mutex protecting HW register
accesses to a spin lock, leaving, however, a long delay in the critical
section protected by the spin lock. This may become a problem,
especially on RT kernels.
To address this, release the spin lock before sleeping for 20 ms as
required by the HW manual and reacquire it afterwards. To avoid other
threads entering the critical section and configuring the HW while the
software is waiting for the OTG initialization to complete, introduce the
otg_initializing variable alongside the otg_init_done completion. Any
other thread trying to configure the HW while the OTG PHY initialization
is in progress waits for the completion instead of immediately returning
errors to PHY users. The IRQs were also disabled while waiting for the OTG
PHY initialization to complete, as the interrupt handler may also apply HW
settings.
Fixes: 55a387ebb921 ("phy: renesas: rcar-gen3-usb2: Lock around hardware registers and driver data")
Cc: stable@vger.kernel.org
Reported-by: Pavel Machek <pavel@nabladev.com>
Closes: https://lore.kernel.org/all/afhkX2Ys2BG1gnqy@duo.ucw.cz
Reported-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
Closes: https://lore.kernel.org/all/afhkX2Ys2BG1gnqy@duo.ucw.cz
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
---
Changes in v2:
- dropped the rcar_gen3_phy_wait_otg_init() and used inline the code; with it
the comment that was previously in rcar_gen3_phy_wait_otg_init() was added
in struct rcar_gen3_chan for above the org_initializing variable
- dropped READ_ONCE()/WRITE_ONCE() arround struct rcar_gen3_chan::otg_initializing
- checked for struct rcar_gen3_chan::otg_initializing before checking for
rcar_gen3_is_any_otg_rphy_initialized() in all code places
- added rcar_gen3_phy_usb2_irqs_mask_all() and rcar_gen3_phy_usb2_irqs_unmask()
to mask/unmask only the interrupts at the controller level since the line is
shared
- along with it dropped disable_irq_nosync()/enable_irq() from v1 along with
struct rcar_gen3_chan::irq
- increased the completion timeout to 30 ms
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 216 +++++++++++++++++++----
1 file changed, 185 insertions(+), 31 deletions(-)
diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 9a45d840efeb..734079a07189 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -138,12 +138,20 @@ struct rcar_gen3_chan {
struct rcar_gen3_phy rphys[NUM_OF_PHYS];
struct regulator *vbus;
struct work_struct work;
+ struct completion otg_init_done;
spinlock_t lock; /* protects access to hardware and driver data structure. */
enum usb_dr_mode dr_mode;
bool extcon_host;
bool is_otg_channel;
bool uses_otg_pins;
bool otg_internal_reg;
+ /*
+ * The OTG can be initialized only once and needs to release the spinlock
+ * and wait for 20 ms due to hardware constraints. If a thread executes
+ * PHY configuration code while the OTG PHY is waiting for the 20 ms, the
+ * thread will have to wait for the OTG PHY initialization to complete.
+ */
+ bool otg_initializing;
};
struct rcar_gen3_phy_drv_data {
@@ -392,26 +400,48 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr,
struct rcar_gen3_chan *ch = dev_get_drvdata(dev);
bool is_b_device;
enum phy_mode cur_mode, new_mode;
+ unsigned long flags;
+ int ret = -EIO;
- guard(spinlock_irqsave)(&ch->lock);
+ spin_lock_irqsave(&ch->lock, flags);
- if (!ch->is_otg_channel || !rcar_gen3_is_any_otg_rphy_initialized(ch))
- return -EIO;
+ if (!ch->is_otg_channel)
+ goto unlock;
+
+ if (ch->otg_initializing) {
+ unsigned long timeout = msecs_to_jiffies(30);
+
+ spin_unlock_irqrestore(&ch->lock, flags);
+
+ ret = wait_for_completion_timeout(&ch->otg_init_done, timeout);
+ ret = ret ? 0 : -ETIMEDOUT;
+ if (ret)
+ return ret;
+
+ spin_lock_irqsave(&ch->lock, flags);
+ }
- if (sysfs_streq(buf, "host"))
+ if (!rcar_gen3_is_any_otg_rphy_initialized(ch))
+ goto unlock;
+
+ if (sysfs_streq(buf, "host")) {
new_mode = PHY_MODE_USB_HOST;
- else if (sysfs_streq(buf, "peripheral"))
+ } else if (sysfs_streq(buf, "peripheral")) {
new_mode = PHY_MODE_USB_DEVICE;
- else
- return -EINVAL;
+ } else {
+ ret = -EINVAL;
+ goto unlock;
+ }
/* is_b_device: true is B-Device. false is A-Device. */
is_b_device = rcar_gen3_check_id(ch);
cur_mode = rcar_gen3_get_phy_mode(ch);
/* If current and new mode is the same, this returns the error */
- if (cur_mode == new_mode)
- return -EINVAL;
+ if (cur_mode == new_mode) {
+ ret = -EINVAL;
+ goto unlock;
+ }
if (new_mode == PHY_MODE_USB_HOST) { /* And is_host must be false */
if (!is_b_device) /* A-Peripheral */
@@ -425,7 +455,10 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr,
rcar_gen3_init_for_peri(ch);
}
- return count;
+unlock:
+ spin_unlock_irqrestore(&ch->lock, flags);
+
+ return ret ?: count;
}
static ssize_t role_show(struct device *dev, struct device_attribute *attr,
@@ -441,14 +474,11 @@ static ssize_t role_show(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RW(role);
-static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
+static void rcar_gen3_init_otg_phase0(struct rcar_gen3_chan *ch)
{
void __iomem *usb2_base = ch->base;
u32 val;
- if (!ch->is_otg_channel || rcar_gen3_is_any_otg_rphy_initialized(ch))
- return;
-
/* Should not use functions of read-modify-write a register */
val = readl(usb2_base + USB2_LINECTRL1);
val = (val & ~USB2_LINECTRL1_DP_RPD) | USB2_LINECTRL1_DPRPD_EN |
@@ -471,7 +501,11 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL);
}
}
- mdelay(20);
+}
+
+static void rcar_gen3_init_otg_phase1(struct rcar_gen3_chan *ch)
+{
+ void __iomem *usb2_base = ch->base;
writel(0xffffffff, usb2_base + USB2_OBINTSTA);
writel(ch->phy_data->obint_enable_bits, usb2_base + USB2_OBINTEN);
@@ -510,6 +544,11 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
goto rpm_put;
scoped_guard(spinlock, &ch->lock) {
+ if (ch->otg_initializing) {
+ ret = IRQ_NONE;
+ goto rpm_put;
+ }
+
status = readl(usb2_base + USB2_OBINTSTA);
if (status & ch->phy_data->obint_enable_bits) {
dev_vdbg(dev, "%s: %08x\n", __func__, status);
@@ -528,14 +567,59 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
return ret;
}
+static void rcar_gen3_phy_usb2_irqs_mask_all(struct rcar_gen3_chan *channel,
+ u32 *masked_irqs_bits)
+{
+ void __iomem *usb2_base = channel->base;
+ u32 val, bitmask = 0;
+
+ for (unsigned int i = 0; i < NUM_OF_PHYS; i++)
+ bitmask |= channel->rphys[i].int_enable_bits;
+
+ val = readl(usb2_base + USB2_INT_ENABLE);
+ *masked_irqs_bits = val & bitmask;
+ val &= ~bitmask;
+ writel(val, usb2_base + USB2_INT_ENABLE);
+}
+
+static void rcar_gen3_phy_usb2_irqs_unmask(struct rcar_gen3_chan *channel,
+ u32 irqs_bits)
+{
+ void __iomem *usb2_base = channel->base;
+ u32 val, bitmask = 0;
+
+ for (unsigned int i = 0; i < NUM_OF_PHYS; i++)
+ bitmask |= channel->rphys[i].int_enable_bits;
+
+ val = readl(usb2_base + USB2_INT_ENABLE);
+ val &= ~bitmask;
+ val |= irqs_bits;
+ writel(val, usb2_base + USB2_INT_ENABLE);
+}
+
static int rcar_gen3_phy_usb2_init(struct phy *p)
{
struct rcar_gen3_phy *rphy = phy_get_drvdata(p);
struct rcar_gen3_chan *channel = rphy->ch;
void __iomem *usb2_base = channel->base;
+ unsigned long flags;
+ int ret = 0;
u32 val;
- guard(spinlock_irqsave)(&channel->lock);
+ spin_lock_irqsave(&channel->lock, flags);
+
+ if (channel->otg_initializing) {
+ unsigned long timeout = msecs_to_jiffies(30);
+
+ spin_unlock_irqrestore(&channel->lock, flags);
+
+ ret = wait_for_completion_timeout(&channel->otg_init_done, timeout);
+ ret = ret ? 0 : -ETIMEDOUT;
+ if (ret)
+ return ret;
+
+ spin_lock_irqsave(&channel->lock, flags);
+ }
/* Initialize USB2 part */
val = readl(usb2_base + USB2_INT_ENABLE);
@@ -548,8 +632,24 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
}
/* Initialize otg part (only if we initialize a PHY with IRQs). */
- if (rphy->int_enable_bits)
- rcar_gen3_init_otg(channel);
+ if (rphy->int_enable_bits && channel->is_otg_channel &&
+ !rcar_gen3_is_any_otg_rphy_initialized(channel)) {
+ u32 masked_irq_bits = 0;
+
+ rcar_gen3_init_otg_phase0(channel);
+ rcar_gen3_phy_usb2_irqs_mask_all(channel, &masked_irq_bits);
+ reinit_completion(&channel->otg_init_done);
+ channel->otg_initializing = true;
+ spin_unlock_irqrestore(&channel->lock, flags);
+
+ fsleep(20000);
+
+ spin_lock_irqsave(&channel->lock, flags);
+ channel->otg_initializing = false;
+ complete_all(&channel->otg_init_done);
+ rcar_gen3_phy_usb2_irqs_unmask(channel, masked_irq_bits);
+ rcar_gen3_init_otg_phase1(channel);
+ }
if (channel->phy_data->vblvl_ctrl) {
/* SIDDQ mode release */
@@ -568,7 +668,9 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
rphy->initialized = true;
- return 0;
+ spin_unlock_irqrestore(&channel->lock, flags);
+
+ return ret;
}
static int rcar_gen3_phy_usb2_exit(struct phy *p)
@@ -576,9 +678,24 @@ static int rcar_gen3_phy_usb2_exit(struct phy *p)
struct rcar_gen3_phy *rphy = phy_get_drvdata(p);
struct rcar_gen3_chan *channel = rphy->ch;
void __iomem *usb2_base = channel->base;
+ unsigned long flags;
+ int ret = 0;
u32 val;
- guard(spinlock_irqsave)(&channel->lock);
+ spin_lock_irqsave(&channel->lock, flags);
+
+ if (channel->otg_initializing) {
+ unsigned long timeout = msecs_to_jiffies(30);
+
+ spin_unlock_irqrestore(&channel->lock, flags);
+
+ ret = wait_for_completion_timeout(&channel->otg_init_done, timeout);
+ ret = ret ? 0 : -ETIMEDOUT;
+ if (ret)
+ return ret;
+
+ spin_lock_irqsave(&channel->lock, flags);
+ }
rphy->initialized = false;
@@ -588,7 +705,8 @@ static int rcar_gen3_phy_usb2_exit(struct phy *p)
val &= ~USB2_INT_ENABLE_UCOM_INTEN;
writel(val, usb2_base + USB2_INT_ENABLE);
- return 0;
+ spin_unlock_irqrestore(&channel->lock, flags);
+ return ret;
}
static int rcar_gen3_phy_usb2_power_on(struct phy *p)
@@ -596,6 +714,7 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p)
struct rcar_gen3_phy *rphy = phy_get_drvdata(p);
struct rcar_gen3_chan *channel = rphy->ch;
void __iomem *usb2_base = channel->base;
+ unsigned long flags;
u32 val;
int ret = 0;
@@ -605,7 +724,20 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p)
return ret;
}
- guard(spinlock_irqsave)(&channel->lock);
+ spin_lock_irqsave(&channel->lock, flags);
+
+ if (channel->otg_initializing) {
+ unsigned long timeout = msecs_to_jiffies(30);
+
+ spin_unlock_irqrestore(&channel->lock, flags);
+
+ ret = wait_for_completion_timeout(&channel->otg_init_done, timeout);
+ ret = ret ? 0 : -ETIMEDOUT;
+ if (ret)
+ return ret;
+
+ spin_lock_irqsave(&channel->lock, flags);
+ }
if (!rcar_gen3_are_all_rphys_power_off(channel))
goto out;
@@ -620,27 +752,48 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p)
/* The powered flag should be set for any other phys anyway */
rphy->powered = true;
- return 0;
+ spin_unlock_irqrestore(&channel->lock, flags);
+
+ if (ret && channel->vbus && !channel->otg_internal_reg)
+ regulator_disable(channel->vbus);
+
+ return ret;
}
static int rcar_gen3_phy_usb2_power_off(struct phy *p)
{
struct rcar_gen3_phy *rphy = phy_get_drvdata(p);
struct rcar_gen3_chan *channel = rphy->ch;
+ unsigned long flags;
int ret = 0;
- scoped_guard(spinlock_irqsave, &channel->lock) {
- rphy->powered = false;
+ spin_lock_irqsave(&channel->lock, flags);
- if (rcar_gen3_are_all_rphys_power_off(channel)) {
- u32 val = readl(channel->base + USB2_USBCTR);
+ if (channel->otg_initializing) {
+ unsigned long timeout = msecs_to_jiffies(30);
- val |= USB2_USBCTR_PLL_RST;
- writel(val, channel->base + USB2_USBCTR);
- }
+ spin_unlock_irqrestore(&channel->lock, flags);
+
+ ret = wait_for_completion_timeout(&channel->otg_init_done, timeout);
+ ret = ret ? 0 : -ETIMEDOUT;
+ if (ret)
+ return ret;
+
+ spin_lock_irqsave(&channel->lock, flags);
}
- if (channel->vbus && !channel->otg_internal_reg)
+ rphy->powered = false;
+
+ if (rcar_gen3_are_all_rphys_power_off(channel)) {
+ u32 val = readl(channel->base + USB2_USBCTR);
+
+ val |= USB2_USBCTR_PLL_RST;
+ writel(val, channel->base + USB2_USBCTR);
+ }
+
+ spin_unlock_irqrestore(&channel->lock, flags);
+
+ if (!ret && channel->vbus && !channel->otg_internal_reg)
ret = regulator_disable(channel->vbus);
return ret;
@@ -1007,6 +1160,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
return ret;
spin_lock_init(&channel->lock);
+ init_completion(&channel->otg_init_done);
for (i = 0; i < NUM_OF_PHYS; i++) {
channel->rphys[i].phy = devm_phy_create(dev, NULL,
channel->phy_data->phy_usb2_ops);
--
2.43.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* Re: [PATCH v3 1/5] dt-bindings: arm: qcom: Document Shikra and its EVK boards
From: Krzysztof Kozlowski @ 2026-05-26 15:45 UTC (permalink / raw)
To: Komal Bajaj
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vinod Koul, Neil Armstrong, Wesley Cheng,
Ulf Hansson, linux-arm-msm, devicetree, linux-kernel, linux-phy,
linux-mmc, monish.chunara
In-Reply-To: <20260522-shikra-dt-v3-1-80ffde8a3dc4@oss.qualcomm.com>
On Fri, May 22, 2026 at 11:32:24PM +0530, Komal Bajaj wrote:
> Shikra is a Qualcomm IoT SoC available in a System-on-Module (SoM)
> form factor. The SoM integrates the Shikra SoC, PMICs, and essential
> passives, and is designed to be mounted on carrier boards.
>
> Three eSoM variant are introduced:
> - CQM: retail variant with integrated modem
> - CQS: retail variant without modem
> - IQS: industrial-grade variant without modem
Industrial/consumer variants differ often only with thermal, so how is
it here? Thermal difference does not make them incompatible. Honestly,
usually industrial one does not even receive dedicated compatibles.
Best regards,
Krzysztof
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: (subset) [PATCH v4 0/5] J722S SGMII support
From: Nishanth Menon @ 2026-05-26 11:52 UTC (permalink / raw)
To: Vignesh Raghavendra, Tero Kristo, Vinod Koul, Neil Armstrong,
Nora Schiffer
Cc: Nishanth Menon, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Siddharth Vadapalli, Roger Quadros,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, netdev,
devicetree, linux-kernel, linux-phy, linux-arm-kernel, linux
In-Reply-To: <cover.1775559102.git.nora.schiffer@ew.tq-group.com>
Hi Nora Schiffer,
On Tue, 07 Apr 2026 13:42:32 +0200, Nora Schiffer wrote:
> The J722S CPSW and SERDES are very similar to the variants found on the
> AM64, but they additionally support SGMII. Introduce new compatible
> strings for the J722S to add this support to the drivers.
>
> This is a prerequisite for the Single-Pair Ethernet interface of the
> TQ-Systems MBa67xx baseboard for the TQMa67xx SoM, which will be
> submitted separately.
>
> [...]
I have applied the following to branch ti-k3-dts-next on [1].
Thank you!
[5/5] arm64: dts: ti: k3-j722s-main: use J722S compatibles for WIZ, gmii-sel and CPSW3G
commit: 2bdc0ea4e7304f6aa7e87089609fd902d9de7a2d
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3 1A34 DDB5 849D 1736 249D
https://ti.com/opensource
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v3 3/3] phy: qcom-qmp-ufs: Add UFS PHY support on Hawi
From: sashiko-bot @ 2026-05-26 10:02 UTC (permalink / raw)
To: palash.kambar
Cc: olteanv, linux-phy, conor+dt, robh, devicetree, vkoul,
neil.armstrong
In-Reply-To: <20260526090956.2340262-4-palash.kambar@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] The Hawi UFS PHY configuration (`hawi_ufsphy_cfg`) lacks a fallback overlay for `UFS_HS_G4`, preventing proper initialization for UFS 3.1 or lower devices.
- [High] Incorrect HSGEAR_CAPABILITY value configured for the UFS HS Gear 5 overlay.
--
commit 1174a7d9d404cf84ecf6ba8228fcab24e26ef4df
Author: Palash Kambar <palash.kambar@oss.qualcomm.com>
phy: qcom-qmp-ufs: Add UFS PHY support on Hawi
This commit adds the initialization sequence tables and configuration
for the UFS QMP PHY found in the Hawi SoC.
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> index 771bc7c2ab505..2fac3a7eb8201 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
[ ... ]
> @@ -1844,6 +1867,119 @@ static const struct qmp_phy_cfg sm8750_ufsphy_cfg = {
>
> };
>
[ ... ]
> +static const struct qmp_phy_init_tbl hawi_ufsphy_g5_pcs[] = {
> + QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_PLL_CNTL, 0x3b),
> + QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x06),
> + QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x06),
[Severity: High]
Does this code advertise an incorrect gear capability?
The overlay is named g5_pcs and the maximum supported gear is UFS_HS_G5, but
these capability registers are being programmed with 0x06. This typically maps
to a Gear 6 capability, which could cause link training failures or mismatches
during UFS negotiation if the value should actually be 0x05.
> +};
> +
> +static const struct qmp_phy_cfg hawi_ufsphy_cfg = {
> + .lanes = 2,
> +
> + .offsets = &qmp_ufs_offsets_v7,
> + .max_supported_gear = UFS_HS_G5,
> +
> + .tbls = {
> + .serdes = hawi_ufsphy_serdes,
> + .serdes_num = ARRAY_SIZE(hawi_ufsphy_serdes),
> + .tx = hawi_ufsphy_tx,
> + .tx_num = ARRAY_SIZE(hawi_ufsphy_tx),
> + .rx = hawi_ufsphy_rx,
> + .rx_num = ARRAY_SIZE(hawi_ufsphy_rx),
> + .pcs = hawi_ufsphy_pcs,
> + .pcs_num = ARRAY_SIZE(hawi_ufsphy_pcs),
> + },
> +
> + .tbls_hs_overlay[0] = {
> + .pcs = hawi_ufsphy_g5_pcs,
> + .pcs_num = ARRAY_SIZE(hawi_ufsphy_g5_pcs),
> + .max_gear = UFS_HS_G5,
> + },
[Severity: High]
Does this configuration lack a fallback overlay for UFS_HS_G4?
If the UFS host controller negotiates Gear 4 (for a UFS 3.1 device) or lower,
qmp_ufs_get_gear_overlay() will attempt to find the closest higher supported
gear overlay. Because floor_max_gear is initialized to cfg->max_supported_gear
(5), the fallback condition max_gear < floor_max_gear evaluates to 5 < 5 (false)
for this single available overlay.
This results in qmp_ufs_get_gear_overlay() returning -EINVAL with no overlay
applied, leaving critical PCS registers uninitialized and causing link
establishment to fail. Should a G4 overlay be added here similar to other
G5-capable PHYs like sm8750_ufsphy_cfg?
> +
> + .vreg_list = hawi_ufsphy_vreg_l,
> + .num_vregs = ARRAY_SIZE(hawi_ufsphy_vreg_l),
> + .regs = ufsphy_v7_regs_layout,
> +};
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260526090956.2340262-1-palash.kambar@oss.qualcomm.com?part=3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v3 2/3] scsi: ufs: qcom: dt-bindings: Document the Hawi UFS controller
From: sashiko-bot @ 2026-05-26 9:37 UTC (permalink / raw)
To: palash.kambar
Cc: conor+dt, robh, devicetree, linux-phy, neil.armstrong, vkoul,
olteanv
In-Reply-To: <20260526090956.2340262-3-palash.kambar@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The new compatible string `qcom,hawi-ufshc` was omitted from the existing `if-then` conditional block that enforces the MCQ register constraints.
--
commit 6ca85cee3094310081f09881b4d6d6a9e987b327
Author: Palash Kambar <palash.kambar@oss.qualcomm.com>
scsi: ufs: qcom: dt-bindings: Document the Hawi UFS controller
Document the UFS Controller on the Hawi Platform.
> diff --git a/Documentation/devicetree/bindings/ufs/qcom,sm8650-ufshc.yaml b/Documentation/devicetree/bindings/ufs/qcom,sm8650-ufshc.yaml
> index f28641c6e68fe..3de00affa4c64 100644
> --- a/Documentation/devicetree/bindings/ufs/qcom,sm8650-ufshc.yaml
> +++ b/Documentation/devicetree/bindings/ufs/qcom,sm8650-ufshc.yaml
[ ... ]
> @@ -27,6 +28,7 @@ properties:
> items:
> - enum:
> - qcom,eliza-ufshc
> + - qcom,hawi-ufshc
> - qcom,kaanapali-ufshc
> - qcom,sm8650-ufshc
> - qcom,sm8750-ufshc
[Severity: Medium]
Should qcom,hawi-ufshc also be added to the allOf conditional block that
enforces the MCQ register constraints?
If the new compatible string shares the same constraints as previous
generations, device tree configurations with only one register region could
silently pass schema validation.
Looking at the existing conditional block lower down in the file:
allOf:
- $ref: qcom,ufs-common.yaml
- if:
properties:
compatible:
contains:
enum:
- qcom,eliza-ufshc
then:
properties:
reg:
minItems: 2
reg-names:
minItems: 2
Does this if-then block need to be updated to include the new compatible
string so the validation remains complete?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260526090956.2340262-1-palash.kambar@oss.qualcomm.com?part=2
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v3 3/3] phy: qcom-qmp-ufs: Add UFS PHY support on Hawi
From: palash.kambar @ 2026-05-26 9:09 UTC (permalink / raw)
To: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, mani, alim.akhtar,
bvanassche, andersson, dmitry.baryshkov, abel.vesa, luca.weiss
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-scsi,
nitin.rawat, Palash Kambar
In-Reply-To: <20260526090956.2340262-1-palash.kambar@oss.qualcomm.com>
From: Palash Kambar <palash.kambar@oss.qualcomm.com>
Add the init sequence tables and config for the UFS QMP phy found in
the Hawi SoC.
Signed-off-by: Palash Kambar <palash.kambar@oss.qualcomm.com>
---
.../phy/qualcomm/phy-qcom-qmp-pcs-ufs-v7.h | 24 +++
.../phy-qcom-qmp-qserdes-txrx-ufs-v8.h | 37 +++++
drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 139 ++++++++++++++++++
3 files changed, 200 insertions(+)
create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v7.h
create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v8.h
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v7.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v7.h
new file mode 100644
index 000000000000..e80d3dd6a190
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v7.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2026, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_PCS_UFS_V7_H_
+#define QCOM_PHY_QMP_PCS_UFS_V7_H_
+
+/* Only for QMP V7 PHY - UFS PCS registers */
+#define QPHY_V7_PCS_UFS_PHY_START 0x000
+#define QPHY_V7_PCS_UFS_POWER_DOWN_CONTROL 0x004
+#define QPHY_V7_PCS_UFS_SW_RESET 0x008
+#define QPHY_V7_PCS_UFS_PCS_CTRL1 0x01C
+#define QPHY_V7_PCS_UFS_PLL_CNTL 0x028
+#define QPHY_V7_PCS_UFS_TX_LARGE_AMP_DRV_LVL 0x02C
+#define QPHY_V7_PCS_UFS_TX_HSGEAR_CAPABILITY 0x060
+#define QPHY_V7_PCS_UFS_RX_HSGEAR_CAPABILITY 0x094
+#define QPHY_V7_PCS_UFS_LINECFG_DISABLE 0x140
+#define QPHY_V7_PCS_UFS_RX_SIGDET_CTRL2 0x150
+#define QPHY_V7_PCS_UFS_READY_STATUS 0x16c
+#define QPHY_V7_PCS_UFS_TX_MID_TERM_CTRL1 0x1b8
+#define QPHY_V7_PCS_UFS_MULTI_LANE_CTRL1 0x1c0
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v8.h
new file mode 100644
index 000000000000..5f923c3e64ec
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v8.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2026, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef QCOM_PHY_QMP_QSERDES_TXRX_UFS_V8_H_
+#define QCOM_PHY_QMP_QSERDES_TXRX_UFS_V8_H_
+
+#define QSERDES_UFS_V8_TX_RES_CODE_LANE_OFFSET_TX (0x34)
+#define QSERDES_UFS_V8_TX_RES_CODE_LANE_OFFSET_RX (0x38)
+#define QSERDES_UFS_V8_TX_LANE_MODE_1 (0x80)
+#define QSERDES_UFS_V8_RX_UCDR_FO_GAIN_RATE2 (0x1BC)
+#define QSERDES_UFS_V8_RX_UCDR_FO_GAIN_RATE4 (0x1C4)
+#define QSERDES_UFS_V8_RX_UCDR_SO_GAIN_RATE4 (0x1DC)
+#define QSERDES_UFS_V8_RX_EQ_OFFSET_ADAPTOR_CNTRL1 (0x2C8)
+#define QSERDES_UFS_V8_RX_UCDR_PI_CONTROLS (0x1E4)
+#define QSERDES_UFS_V8_RX_OFFSET_ADAPTOR_CNTRL3 (0x2D0)
+#define QSERDES_UFS_V8_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4 (0x120)
+#define QSERDES_UFS_V8_RX_UCDR_FASTLOCK_FO_GAIN_RATE4 (0xD4)
+#define QSERDES_UFS_V8_RX_UCDR_FASTLOCK_SO_GAIN_RATE4 (0xEC)
+#define QSERDES_UFS_V8_RX_VGA_CAL_MAN_VAL (0x288)
+#define QSERDES_UFS_V8_RX_EQU_ADAPTOR_CNTRL4 (0x2B0)
+#define QSERDES_UFS_V8_RX_MODE_RATE_0_1_B4 (0x324)
+#define QSERDES_UFS_V8_RX_MODE_RATE4_SA_B7 (0x3B4)
+#define QSERDES_UFS_V8_RX_MODE_RATE4_SA_B9 (0x3BC)
+#define QSERDES_UFS_V8_RX_MODE_RATE4_SB_B7 (0x3E0)
+#define QSERDES_UFS_V8_RX_MODE_RATE4_SB_B9 (0x3E8)
+#define QSERDES_UFS_V8_RX_MODE_RATE5_SA_B7 (0x40C)
+#define QSERDES_UFS_V8_RX_MODE_RATE5_SA_B9 (0x414)
+#define QSERDES_UFS_V8_RX_MODE_RATE5_SB_B7 (0x438)
+#define QSERDES_UFS_V8_RX_MODE_RATE5_SB_B9 (0x440)
+#define QSERDES_UFS_V8_RX_UCDR_SO_SATURATION (0xF4)
+#define QSERDES_UFS_V8_RX_TERM_BW_CTRL0 (0x1AC)
+#define QSERDES_UFS_V8_RX_DLL0_FTUNE_CTRL (0x498)
+#define QSERDES_UFS_V8_RX_SIGDET_CAL_TRIM (0x4d0)
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
index 771bc7c2ab50..2fac3a7eb820 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
@@ -29,9 +29,11 @@
#include "phy-qcom-qmp-pcs-ufs-v4.h"
#include "phy-qcom-qmp-pcs-ufs-v5.h"
#include "phy-qcom-qmp-pcs-ufs-v6.h"
+#include "phy-qcom-qmp-pcs-ufs-v7.h"
#include "phy-qcom-qmp-qserdes-txrx-ufs-v6.h"
#include "phy-qcom-qmp-qserdes-txrx-ufs-v7.h"
+#include "phy-qcom-qmp-qserdes-txrx-ufs-v8.h"
/* QPHY_PCS_READY_STATUS bit */
#define PCS_READY BIT(0)
@@ -84,6 +86,13 @@ static const unsigned int ufsphy_v6_regs_layout[QPHY_LAYOUT_SIZE] = {
[QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V6_PCS_UFS_POWER_DOWN_CONTROL,
};
+static const unsigned int ufsphy_v7_regs_layout[QPHY_LAYOUT_SIZE] = {
+ [QPHY_START_CTRL] = QPHY_V7_PCS_UFS_PHY_START,
+ [QPHY_PCS_READY_STATUS] = QPHY_V7_PCS_UFS_READY_STATUS,
+ [QPHY_SW_RESET] = QPHY_V7_PCS_UFS_SW_RESET,
+ [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V7_PCS_UFS_POWER_DOWN_CONTROL,
+};
+
static const struct qmp_phy_init_tbl milos_ufsphy_serdes[] = {
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
@@ -1306,6 +1315,11 @@ static const struct regulator_bulk_data sm8750_ufsphy_vreg_l[] = {
{ .supply = "vdda-pll", .init_load_uA = 18300 },
};
+static const struct regulator_bulk_data hawi_ufsphy_vreg_l[] = {
+ { .supply = "vdda-phy", .init_load_uA = 324000 },
+ { .supply = "vdda-pll", .init_load_uA = 27000 },
+};
+
static const struct qmp_ufs_offsets qmp_ufs_offsets = {
.serdes = 0,
.pcs = 0xc00,
@@ -1324,6 +1338,15 @@ static const struct qmp_ufs_offsets qmp_ufs_offsets_v6 = {
.rx2 = 0x1a00,
};
+static const struct qmp_ufs_offsets qmp_ufs_offsets_v7 = {
+ .serdes = 0,
+ .pcs = 0x0400,
+ .tx = 0x2000,
+ .rx = 0x2000,
+ .tx2 = 0x3000,
+ .rx2 = 0x3000,
+};
+
static const struct qmp_phy_cfg milos_ufsphy_cfg = {
.lanes = 2,
@@ -1844,6 +1867,119 @@ static const struct qmp_phy_cfg sm8750_ufsphy_cfg = {
};
+static const struct qmp_phy_init_tbl hawi_ufsphy_serdes[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_SYSCLK_EN_SEL, 0xd9),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_CONFIG_1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_HSCLK_SEL_1, 0x11),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP_EN, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP_CFG, 0x60),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_IVCO, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_IVCO_MODE1, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_IETRIM, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_IPTRIM, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE_MAP, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE_CTRL, 0x40),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_ADAPTIVE_ANALOG_CONFIG, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE0, 0x41),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE0, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE0, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE0, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_ADAPTIVE_MODE0, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCCTRL_ADAPTIVE_MODE0, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_ADAPTIVE_MODE0, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE0, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE0, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x92),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE1, 0x4c),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE1, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE1, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE1, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_ADAPTIVE_MODE1, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCCTRL_ADAPTIVE_MODE1, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_ADAPTIVE_MODE1, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE1, 0x99),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE1, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xbe),
+ QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
+};
+
+static const struct qmp_phy_init_tbl hawi_ufsphy_tx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_TX_LANE_MODE_1, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_TX_RES_CODE_LANE_OFFSET_RX, 0x17),
+};
+
+static const struct qmp_phy_init_tbl hawi_ufsphy_rx[] = {
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_UCDR_FO_GAIN_RATE2, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_UCDR_FO_GAIN_RATE4, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_UCDR_SO_GAIN_RATE4, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_UCDR_PI_CONTROLS, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_OFFSET_ADAPTOR_CNTRL3, 0x0e),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x1c),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_VGA_CAL_MAN_VAL, 0x8e),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_EQU_ADAPTOR_CNTRL4, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_MODE_RATE_0_1_B4, 0xb8),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_MODE_RATE4_SA_B7, 0x66),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_MODE_RATE4_SA_B9, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_MODE_RATE4_SB_B7, 0x66),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_MODE_RATE4_SB_B9, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_MODE_RATE5_SA_B7, 0x66),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_MODE_RATE5_SA_B9, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_MODE_RATE5_SB_B7, 0x66),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_MODE_RATE5_SB_B9, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_UCDR_SO_SATURATION, 0x1f),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_TERM_BW_CTRL0, 0xfa),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_DLL0_FTUNE_CTRL, 0x30),
+ QMP_PHY_INIT_CFG(QSERDES_UFS_V8_RX_SIGDET_CAL_TRIM, 0x77),
+};
+
+static const struct qmp_phy_init_tbl hawi_ufsphy_pcs[] = {
+ QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
+ QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_PCS_CTRL1, 0x42),
+ QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
+ QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_RX_SIGDET_CTRL2, 0x68),
+ QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
+};
+
+static const struct qmp_phy_init_tbl hawi_ufsphy_g5_pcs[] = {
+ QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_PLL_CNTL, 0x3b),
+ QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x06),
+ QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x06),
+};
+
+static const struct qmp_phy_cfg hawi_ufsphy_cfg = {
+ .lanes = 2,
+
+ .offsets = &qmp_ufs_offsets_v7,
+ .max_supported_gear = UFS_HS_G5,
+
+ .tbls = {
+ .serdes = hawi_ufsphy_serdes,
+ .serdes_num = ARRAY_SIZE(hawi_ufsphy_serdes),
+ .tx = hawi_ufsphy_tx,
+ .tx_num = ARRAY_SIZE(hawi_ufsphy_tx),
+ .rx = hawi_ufsphy_rx,
+ .rx_num = ARRAY_SIZE(hawi_ufsphy_rx),
+ .pcs = hawi_ufsphy_pcs,
+ .pcs_num = ARRAY_SIZE(hawi_ufsphy_pcs),
+ },
+
+ .tbls_hs_overlay[0] = {
+ .pcs = hawi_ufsphy_g5_pcs,
+ .pcs_num = ARRAY_SIZE(hawi_ufsphy_g5_pcs),
+ .max_gear = UFS_HS_G5,
+ },
+
+ .vreg_list = hawi_ufsphy_vreg_l,
+ .num_vregs = ARRAY_SIZE(hawi_ufsphy_vreg_l),
+ .regs = ufsphy_v7_regs_layout,
+};
+
static void qmp_ufs_serdes_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls *tbls)
{
void __iomem *serdes = qmp->serdes;
@@ -2258,6 +2394,9 @@ static int qmp_ufs_probe(struct platform_device *pdev)
static const struct of_device_id qmp_ufs_of_match_table[] = {
{
+ .compatible = "qcom,hawi-qmp-ufs-phy",
+ .data = &hawi_ufsphy_cfg,
+ }, {
.compatible = "qcom,milos-qmp-ufs-phy",
.data = &milos_ufsphy_cfg,
}, {
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v3 2/3] scsi: ufs: qcom: dt-bindings: Document the Hawi UFS controller
From: palash.kambar @ 2026-05-26 9:09 UTC (permalink / raw)
To: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, mani, alim.akhtar,
bvanassche, andersson, dmitry.baryshkov, abel.vesa, luca.weiss
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-scsi,
nitin.rawat, Palash Kambar
In-Reply-To: <20260526090956.2340262-1-palash.kambar@oss.qualcomm.com>
From: Palash Kambar <palash.kambar@oss.qualcomm.com>
Document the UFS Controller on the Hawi Platform.
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
Signed-off-by: Palash Kambar <palash.kambar@oss.qualcomm.com>
---
Documentation/devicetree/bindings/ufs/qcom,sm8650-ufshc.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/ufs/qcom,sm8650-ufshc.yaml b/Documentation/devicetree/bindings/ufs/qcom,sm8650-ufshc.yaml
index f28641c6e68f..3de00affa4c6 100644
--- a/Documentation/devicetree/bindings/ufs/qcom,sm8650-ufshc.yaml
+++ b/Documentation/devicetree/bindings/ufs/qcom,sm8650-ufshc.yaml
@@ -16,6 +16,7 @@ select:
contains:
enum:
- qcom,eliza-ufshc
+ - qcom,hawi-ufshc
- qcom,kaanapali-ufshc
- qcom,sm8650-ufshc
- qcom,sm8750-ufshc
@@ -27,6 +28,7 @@ properties:
items:
- enum:
- qcom,eliza-ufshc
+ - qcom,hawi-ufshc
- qcom,kaanapali-ufshc
- qcom,sm8650-ufshc
- qcom,sm8750-ufshc
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v3 1/3] dt-bindings: phy: qcom,sc8280xp-qmp-ufs-phy: Add Hawi UFS PHY compatible
From: palash.kambar @ 2026-05-26 9:09 UTC (permalink / raw)
To: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, mani, alim.akhtar,
bvanassche, andersson, dmitry.baryshkov, abel.vesa, luca.weiss
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-scsi,
nitin.rawat, Palash Kambar
In-Reply-To: <20260526090956.2340262-1-palash.kambar@oss.qualcomm.com>
From: Palash Kambar <palash.kambar@oss.qualcomm.com>
Document QMP UFS PHY compatible for Hawi SoC.
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
Signed-off-by: Palash Kambar <palash.kambar@oss.qualcomm.com>
---
.../devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
index 9616c736b6d4..b75015f3ea70 100644
--- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
@@ -37,6 +37,7 @@ properties:
- qcom,kaanapali-qmp-ufs-phy
- const: qcom,sm8750-qmp-ufs-phy
- enum:
+ - qcom,hawi-qmp-ufs-phy
- qcom,milos-qmp-ufs-phy
- qcom,msm8996-qmp-ufs-phy
- qcom,msm8998-qmp-ufs-phy
@@ -107,6 +108,7 @@ allOf:
compatible:
contains:
enum:
+ - qcom,hawi-qmp-ufs-phy
- qcom,milos-qmp-ufs-phy
- qcom,msm8998-qmp-ufs-phy
- qcom,sa8775p-qmp-ufs-phy
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v3 0/3] Add Hawi UFS PHY and Controller support
From: palash.kambar @ 2026-05-26 9:09 UTC (permalink / raw)
To: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, mani, alim.akhtar,
bvanassche, andersson, dmitry.baryshkov, abel.vesa, luca.weiss
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-scsi,
nitin.rawat, Palash Kambar
From: Palash Kambar <palash.kambar@oss.qualcomm.com>
This series introduces devicetree binding documentation and PHY
initialization support required to enable UFS on this platform.
1. Devicetree binding documentation for the QMP UFS PHY
used on Qualcomm Hawi.
2. Devicetree binding documentation for the UFS controller
instance present on the Hawi platform.
3. Initialization sequence tables and configuration required
for the QMP UFS PHY on Hawi SoC.
---
changes from V1
1) Addressed Dmitry's comments to fix versioning for PCS and qserdes.
2) Addressed Mani's comments and fixed missed compatible string and
binding name correction.
changes from V2
1) Addressed Dmitry's comments to remove whitespace and stray line.
Palash Kambar (3):
dt-bindings: phy: qcom,sc8280xp-qmp-ufs-phy: Add Hawi UFS PHY
compatible
scsi: ufs: qcom: dt-bindings: Document the Hawi UFS controller
phy: qcom-qmp-ufs: Add UFS PHY support on Hawi
.../phy/qcom,sc8280xp-qmp-ufs-phy.yaml | 2 +
.../bindings/ufs/qcom,sm8650-ufshc.yaml | 2 +
.../phy/qualcomm/phy-qcom-qmp-pcs-ufs-v7.h | 24 +++
.../phy-qcom-qmp-qserdes-txrx-ufs-v8.h | 37 +++++
drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 139 ++++++++++++++++++
5 files changed, 204 insertions(+)
create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v7.h
create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v8.h
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox