[PATCH 03/10] phy: qcom-usb-hsic: do not run the sleep calibration clock

From: Dmitry Baryshkov

Date: Mon Aug 10 2026 - 12:35:44 EST


With the cal_sleep (32 kHz IO calibration sleep) clock running, the
HSIC PHY engages its sleep calibration: the strobe/data pad
calibration converges to different values than with the active
calibration alone, HSIC_CFG reports the sleep calibration state, and
the port no longer detects a device connect - an onboard HSIC hub
signalling its attach after reset is never seen (observed on the
APQ8074 Dragonboard against its USB4604 hub, by comparing the ULPI
register state against the vendor kernel, which never enables this
clock: with cal_sleep enabled ULPI HSIC_CFG reads 0xab and the pad
registers 0x0f/0x0d, without it 0xa9 and 0x10/0x10, matching the
working vendor configuration).

Stop requesting and enabling the cal_sleep clock.

Assisted-by: Claude:claude-fable-5
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxxxxxxxx>
---
drivers/phy/qualcomm/phy-qcom-usb-hsic.c | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-usb-hsic.c b/drivers/phy/qualcomm/phy-qcom-usb-hsic.c
index 20f6dd37c7c1..b670ec364a2d 100644
--- a/drivers/phy/qualcomm/phy-qcom-usb-hsic.c
+++ b/drivers/phy/qualcomm/phy-qcom-usb-hsic.c
@@ -20,7 +20,6 @@ struct qcom_usb_hsic_phy {
struct pinctrl *pctl;
struct clk *phy_clk;
struct clk *cal_clk;
- struct clk *cal_sleep_clk;
};

static int qcom_usb_hsic_phy_power_on(struct phy *phy)
@@ -38,9 +37,13 @@ static int qcom_usb_hsic_phy_power_on(struct phy *phy)
if (ret)
goto err_cal;

- ret = clk_prepare_enable(uphy->cal_sleep_clk);
- if (ret)
- goto err_sleep;
+ /*
+ * The sleep calibration clock must not run: with it enabled the PHY
+ * engages sleep calibration (the strobe/data pad calibration
+ * converges to different values and HSIC_CFG reports the sleep
+ * calibration state), and the port does not detect a device connect.
+ * The vendor driver never enables this clock.
+ */

/* Set periodic calibration interval to ~2.048sec in HSIC_IO_CAL_REG */
ret = ulpi_write(ulpi, ULPI_HSIC_IO_CAL, 0xff);
@@ -76,8 +79,6 @@ static int qcom_usb_hsic_phy_power_on(struct phy *phy)

return ret;
err_ulpi:
- clk_disable_unprepare(uphy->cal_sleep_clk);
-err_sleep:
clk_disable_unprepare(uphy->cal_clk);
err_cal:
clk_disable_unprepare(uphy->phy_clk);
@@ -88,7 +89,6 @@ static int qcom_usb_hsic_phy_power_off(struct phy *phy)
{
struct qcom_usb_hsic_phy *uphy = phy_get_drvdata(phy);

- clk_disable_unprepare(uphy->cal_sleep_clk);
clk_disable_unprepare(uphy->cal_clk);
clk_disable_unprepare(uphy->phy_clk);

@@ -125,10 +125,6 @@ static int qcom_usb_hsic_phy_probe(struct ulpi *ulpi)
if (IS_ERR(clk))
return PTR_ERR(clk);

- uphy->cal_sleep_clk = clk = devm_clk_get(&ulpi->dev, "cal_sleep");
- if (IS_ERR(clk))
- return PTR_ERR(clk);
-
uphy->phy = devm_phy_create(&ulpi->dev, ulpi->dev.of_node,
&qcom_usb_hsic_phy_ops);
if (IS_ERR(uphy->phy))

--
2.47.3