* [PATCH v4 2/2] phy: qcom-qmp-ufs: Add UFS PHY support on Hawi
From: palash.kambar @ 2026-06-15 9:12 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: <20260615091242.1617492-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.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Palash Kambar <palash.kambar@oss.qualcomm.com>
---
.../phy/qualcomm/phy-qcom-qmp-pcs-ufs-v7.h | 24 +++
.../qualcomm/phy-qcom-qmp-qserdes-com-v8.h | 13 +-
.../phy-qcom-qmp-qserdes-txrx-ufs-v8.h | 37 +++++
drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 139 ++++++++++++++++++
4 files changed, 212 insertions(+), 1 deletion(-)
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-com-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v8.h
index d8ac4c4a2c31..d416113bcb3c 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v8.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v8.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2026, The Linux Foundation. All rights reserved.
*/
#ifndef QCOM_PHY_QMP_QSERDES_COM_V8_H_
@@ -71,5 +71,16 @@
#define QSERDES_V8_COM_ADDITIONAL_MISC 0x1b4
#define QSERDES_V8_COM_CMN_STATUS 0x2c8
#define QSERDES_V8_COM_C_READY_STATUS 0x2f0
+#define QSERDES_V8_COM_PLL_IVCO_MODE1 0xf8
+#define QSERDES_V8_COM_CMN_IETRIM 0xfc
+#define QSERDES_V8_COM_CMN_IPTRIM 0x100
+#define QSERDES_V8_COM_VCO_TUNE_CTRL 0x13c
+#define QSERDES_V8_COM_ADAPTIVE_ANALOG_CONFIG 0x268
+#define QSERDES_V8_COM_CP_CTRL_ADAPTIVE_MODE0 0x26c
+#define QSERDES_V8_COM_PLL_RCCTRL_ADAPTIVE_MODE0 0x270
+#define QSERDES_V8_COM_PLL_CCTRL_ADAPTIVE_MODE0 0x274
+#define QSERDES_V8_COM_CP_CTRL_ADAPTIVE_MODE1 0x278
+#define QSERDES_V8_COM_PLL_RCCTRL_ADAPTIVE_MODE1 0x27c
+#define QSERDES_V8_COM_PLL_CCTRL_ADAPTIVE_MODE1 0x280
#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 0f4ad24aa405..d4aca22c181e 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),
@@ -1307,6 +1316,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,
@@ -1325,6 +1339,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,
@@ -1845,6 +1868,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, 0x05),
+ QMP_PHY_INIT_CFG(QPHY_V7_PCS_UFS_RX_HSGEAR_CAPABILITY, 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,
+ },
+
+ .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;
@@ -2259,6 +2395,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
* Re: [PATCH 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled VBUS regulator
From: Claudiu Beznea @ 2026-06-15 9:37 UTC (permalink / raw)
To: Biju, Yoshihiro Shimoda, Vinod Koul, Geert Uytterhoeven,
Magnus Damm
Cc: Biju Das, Neil Armstrong, Philipp Zabel, linux-renesas-soc,
linux-phy, linux-kernel, Prabhakar Mahadev Lad
In-Reply-To: <20260612143048.317907-10-biju.das.jz@bp.renesas.com>
Hi, Biju,
On 6/12/26 17:30, Biju wrote:
> From: Biju Das <biju.das.jz@bp.renesas.com>
>
> devm_regulator_get_exclusive() initialises the regulator with
> enable_count = 1, requiring the consumer to disable it before release.
>
> Previously, the devm disable action was only registered when the
> regulator was explicitly enabled, causing the cleanup path to skip
> decrementing enable_count on device removal when the regulator was
> left disabled.
>
> Fix this by always registering the devm disable action when the regulator
> is enabled (checked via regulator_is_enabled()), covering both the
> explicitly-enabled case and the initial state set by
> devm_regulator_get_exclusive().
>
> This fixes WARN_ON enable count during regulator release.
>
> Fixes: 24843404efe4 ("phy: renesas: phy-rcar-gen3-usb2: Control VBUS for RZ/G2L SoCs")
> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
The approach in this patch don't solve the problem, at least on RZ/G3S. See [1]
for logs.
I applied this patch on next-20260610:
git log --oneline -2
afe09f11d549 (HEAD) phy: renesas: phy-rcar-gen3-usb2: Fix devm action
registration for disabled VBUS regulator
abe651837cb3 (tag: next-20260610, linux-next/master) Add linux-next specific
files for 20260610
[1]
https://github.com/claudiubeznea/logs/blob/2f1bab20407dfe6031385819ffeabfc4eac772bd/logs
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* RE: [PATCH 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled VBUS regulator
From: Biju Das @ 2026-06-15 10:22 UTC (permalink / raw)
To: Claudiu.Beznea, biju.das.au, Yoshihiro Shimoda, Vinod Koul,
Geert Uytterhoeven, magnus.damm
Cc: Neil Armstrong, Philipp Zabel, linux-renesas-soc@vger.kernel.org,
linux-phy@lists.infradead.org, linux-kernel@vger.kernel.org,
Prabhakar Mahadev Lad
In-Reply-To: <2b794049-0c44-4390-a6cd-e5bde5c5f3ca@tuxon.dev>
Hi Claudiu,
> -----Original Message-----
> From: Claudiu Beznea <claudiu.beznea@tuxon.dev>
> Sent: 15 June 2026 10:37
> Subject: Re: [PATCH 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled
> VBUS regulator
>
> Hi, Biju,
>
> On 6/12/26 17:30, Biju wrote:
> > From: Biju Das <biju.das.jz@bp.renesas.com>
> >
> > devm_regulator_get_exclusive() initialises the regulator with
> > enable_count = 1, requiring the consumer to disable it before release.
> >
> > Previously, the devm disable action was only registered when the
> > regulator was explicitly enabled, causing the cleanup path to skip
> > decrementing enable_count on device removal when the regulator was
> > left disabled.
> >
> > Fix this by always registering the devm disable action when the
> > regulator is enabled (checked via regulator_is_enabled()), covering
> > both the explicitly-enabled case and the initial state set by
> > devm_regulator_get_exclusive().
> >
> > This fixes WARN_ON enable count during regulator release.
> >
> > Fixes: 24843404efe4 ("phy: renesas: phy-rcar-gen3-usb2: Control VBUS
> > for RZ/G2L SoCs")
> > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
>
> The approach in this patch don't solve the problem, at least on RZ/G3S. See [1] for logs.
>
> I applied this patch on next-20260610:
>
> git log --oneline -2
> afe09f11d549 (HEAD) phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled VBUS
> regulator
> abe651837cb3 (tag: next-20260610, linux-next/master) Add linux-next specific files for 20260610
>
> [1]
> https://github.com/claudiubeznea/logs/blob/2f1bab20407dfe6031385819ffeabfc4eac772bd/logs
I have tested only with RZ/G3L host and I don't see the issue.
How can the issue be reproduced? It could be related to RZ/G3S.
I have executed the following tests and don't see any issue.
Can you please try the same tests on RZ/G3S?
Is unbind/bind ever worked on RZ?G3S previously?
Test1: Host unbind/bind:
cd /sys/bus/platform/drivers/ohci-platform/
echo 11e10000.usb > unbind
echo 11e90000.usb > unbind
cd /sys/bus/platform/drivers/ehci-platform/
echo 11e10100.usb > unbind
echo 11e90100.usb > unbind
cd /sys/bus/platform/drivers/ohci-platform/
echo 11e10000.usb > bind
echo 11e90000.usb > bind
cd /sys/bus/platform/drivers/ehci-platform/
echo 11e10100.usb > bind
echo 11e90100.usb > bind
Test 2 Function unbind/bind:
cd /sys/bus/platform/drivers/renesas_usbhs
echo 11e30000.usb > unbind
cd /sys/bus/platform/drivers/renesas_usbhs
echo 11e30000.usb > bind
Test 3: PHY unbind/bind
cd /sys/bus/platform/drivers/phy_rcar_gen3_usb2
echo 11e10200.usb-phy > unbind
echo 11e90200.usb-phy > unbind
cd /sys/bus/platform/drivers/phy_rcar_gen3_usb2
echo 11e10200.usb-phy > bind
echo 11e90200.usb-phy > bind
Test 4: Regulator unbind/bind
cd /sys/bus/platform/drivers/phy_rcar_gen3_usb2
echo 11e10200.usb-phy > unbind
echo 11e90200.usb-phy > unbind
cd /sys/bus/platform/drivers/rzg3l-usb-vbus-regulator
echo rzg3l-usb-vbus-regulator > unbind
cd /sys/bus/platform/drivers/rzg3l-usb-vbus-regulator
echo rzg3l-usb-vbus-regulator > bind
cd /sys/bus/platform/drivers/phy_rcar_gen3_usb2
echo 11e10200.usb-phy > bind
echo 11e90200.usb-phy > bind
Test 5: Reset unbind/bind
echo "####unbind########"
cd /sys/bus/platform/drivers/rzg2l_usbphy_ctrl
echo 11e00000.usbphy-ctrl > unbind
echo "####bind########"
cd /sys/bus/platform/drivers/rzg2l_usbphy_ctrl
echo 11e00000.usbphy-ctrl > bind
Cheers,
Biju
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 2/4] phy: qcom-qusb2: Fix SM6115 init sequence
From: Konrad Dybcio @ 2026-06-15 10:44 UTC (permalink / raw)
To: Iskren Chernev, Konrad Dybcio, Vinod Koul, Neil Armstrong,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Wesley Cheng,
Greg Kroah-Hartman, Bjorn Andersson
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel
In-Reply-To: <5b474af3-f651-4a64-a5b9-c18136e589eb@iskren.info>
On 6/14/26 2:29 PM, Iskren Chernev wrote:
>
>
> On 6/10/26 3:04 PM, Konrad Dybcio wrote:
>> From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>>
>> I don't know where the existing one came from, but it's apparently
>> wrong, according to both docs and a downstream DT [1]. Fix it up.
>
> They came from DTB extracted from a running billie2 (OnePlus Nord N100):
> [1] https://mainlining.dev/wp-content/uploads/2021/02/03_dtbdump_Qualcomm_Technologies_Inc._Bengal_SoC.dts
>
> The phone was bough early after launch, so it could have been wrong/updated later.
Good to see you're still around!
Looks like vendor tuning. I see that even the initial commit for
6115 had the init sequence I posted. And the OnePlus sources have
what seems like a project-specific local copy of the DTSI:
https://github.com/OnePlusOSS/android_kernel_oneplus_sm4250/blob/oneplus/SM4250_Q_10.0/arch/arm64/boot/dts/vendor/qcom/bengal-usb.dtsi#L145
https://github.com/OnePlusOSS/android_kernel_oneplus_sm4250/blob/oneplus/SM4250_Q_10.0/arch/arm64/boot/dts/vendor/20882/bengal-usb.dtsi#L148
To support that, we should add a new property to override the TUNEx
registers - like e.g. qcom,hstx-trim-value that's already consumed
Would you like to look into that, or should I take this?
Konrad
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* RE: [PATCH 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled VBUS regulator
From: Biju Das @ 2026-06-15 11:41 UTC (permalink / raw)
To: Claudiu.Beznea, biju.das.au, Yoshihiro Shimoda, Vinod Koul,
Geert Uytterhoeven, magnus.damm
Cc: Neil Armstrong, Philipp Zabel, linux-renesas-soc@vger.kernel.org,
linux-phy@lists.infradead.org, linux-kernel@vger.kernel.org,
Prabhakar Mahadev Lad
In-Reply-To: <TY3PR01MB113466284D6307E1967286AC486E62@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Hi Claudiu,
> -----Original Message-----
> From: Biju Das
> Sent: 15 June 2026 11:22
> Subject: RE: [PATCH 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled
> VBUS regulator
>
> Hi Claudiu,
>
> > -----Original Message-----
> > From: Claudiu Beznea <claudiu.beznea@tuxon.dev>
> > Sent: 15 June 2026 10:37
> > Subject: Re: [PATCH 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix devm
> > action registration for disabled VBUS regulator
> >
> > Hi, Biju,
> >
> > On 6/12/26 17:30, Biju wrote:
> > > From: Biju Das <biju.das.jz@bp.renesas.com>
> > >
> > > devm_regulator_get_exclusive() initialises the regulator with
> > > enable_count = 1, requiring the consumer to disable it before release.
> > >
> > > Previously, the devm disable action was only registered when the
> > > regulator was explicitly enabled, causing the cleanup path to skip
> > > decrementing enable_count on device removal when the regulator was
> > > left disabled.
> > >
> > > Fix this by always registering the devm disable action when the
> > > regulator is enabled (checked via regulator_is_enabled()), covering
> > > both the explicitly-enabled case and the initial state set by
> > > devm_regulator_get_exclusive().
> > >
> > > This fixes WARN_ON enable count during regulator release.
> > >
> > > Fixes: 24843404efe4 ("phy: renesas: phy-rcar-gen3-usb2: Control VBUS
> > > for RZ/G2L SoCs")
> > > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
> >
> > The approach in this patch don't solve the problem, at least on RZ/G3S. See [1] for logs.
> >
> > I applied this patch on next-20260610:
> >
> > git log --oneline -2
> > afe09f11d549 (HEAD) phy: renesas: phy-rcar-gen3-usb2: Fix devm action
> > registration for disabled VBUS regulator
> > abe651837cb3 (tag: next-20260610, linux-next/master) Add linux-next
> > specific files for 20260610
> >
> > [1]
> > https://github.com/claudiubeznea/logs/blob/2f1bab20407dfe6031385819ffe
> > abfc4eac772bd/logs
>
> I have tested only with RZ/G3L host and I don't see the issue.
> How can the issue be reproduced? It could be related to RZ/G3S.
> I have executed the following tests and don't see any issue.
> Can you please try the same tests on RZ/G3S?
> Is unbind/bind ever worked on RZ?G3S previously?
Looks like your issue is related to USB function/gadget driver related.
I was testing with USB2.0 host and I did not face this issue.
But after enabling the USB function, I can reproduce the issue you mentioned.
Reason:
rcar_gen3_phy_usb2_power_off() is not called during usbhs/gadget unbind.
You can verify regulator count with
cat /sys/kernel/debug/regulator/regulator_summary
Cheers,
Biju
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled VBUS regulator
From: Claudiu Beznea @ 2026-06-15 11:44 UTC (permalink / raw)
To: Biju Das, biju.das.au, Yoshihiro Shimoda, Vinod Koul,
Geert Uytterhoeven, magnus.damm
Cc: Neil Armstrong, Philipp Zabel, linux-renesas-soc@vger.kernel.org,
linux-phy@lists.infradead.org, linux-kernel@vger.kernel.org,
Prabhakar Mahadev Lad
In-Reply-To: <TY3PR01MB113466284D6307E1967286AC486E62@TY3PR01MB11346.jpnprd01.prod.outlook.com>
On 6/15/26 13:22, Biju Das wrote:
> Hi Claudiu,
>
>> -----Original Message-----
>> From: Claudiu Beznea <claudiu.beznea@tuxon.dev>
>> Sent: 15 June 2026 10:37
>> Subject: Re: [PATCH 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled
>> VBUS regulator
>>
>> Hi, Biju,
>>
>> On 6/12/26 17:30, Biju wrote:
>>> From: Biju Das <biju.das.jz@bp.renesas.com>
>>>
>>> devm_regulator_get_exclusive() initialises the regulator with
>>> enable_count = 1, requiring the consumer to disable it before release.
>>>
>>> Previously, the devm disable action was only registered when the
>>> regulator was explicitly enabled, causing the cleanup path to skip
>>> decrementing enable_count on device removal when the regulator was
>>> left disabled.
>>>
>>> Fix this by always registering the devm disable action when the
>>> regulator is enabled (checked via regulator_is_enabled()), covering
>>> both the explicitly-enabled case and the initial state set by
>>> devm_regulator_get_exclusive().
>>>
>>> This fixes WARN_ON enable count during regulator release.
>>>
>>> Fixes: 24843404efe4 ("phy: renesas: phy-rcar-gen3-usb2: Control VBUS
>>> for RZ/G2L SoCs")
>>> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
>>
>> The approach in this patch don't solve the problem, at least on RZ/G3S. See [1] for logs.
>>
>> I applied this patch on next-20260610:
>>
>> git log --oneline -2
>> afe09f11d549 (HEAD) phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled VBUS
>> regulator
>> abe651837cb3 (tag: next-20260610, linux-next/master) Add linux-next specific files for 20260610
>>
>> [1]
>> https://github.com/claudiubeznea/logs/blob/2f1bab20407dfe6031385819ffeabfc4eac772bd/logs
>
> I have tested only with RZ/G3L host and I don't see the issue.
> How can the issue be reproduced? It could be related to RZ/G3S.
It's reproducible with this patch on G2L as well, please see
https://github.com/claudiubeznea/logs/blob/0601044903b5ae714592db9770bc4ed31fd8bf84/logs.
> I have executed the following tests and don't see any issue.
> Can you please try the same tests on RZ/G3S?
Try stressing it a bit, e.g. the following command trigger it on both G3S and G2L:
cnt=300; while [ $cnt -ge 0 ]; do echo 11c40000.usbphy-ctrl > unbind ; echo
11c40000.usbphy-ctrl > bind ; cnt=$((cnt-1)); done
Same command could be executed for other USB drivers.
> Is unbind/bind ever worked on RZ?G3S previously?
In the same way it works on G2L: functionality is OK, these stack traces are
displayed as on any other RZ/G2L based SoCs.
Thank you,
Claudiu
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* RE: [PATCH 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled VBUS regulator
From: Biju Das @ 2026-06-15 11:50 UTC (permalink / raw)
To: Claudiu.Beznea, biju.das.au, Yoshihiro Shimoda, Vinod Koul,
Geert Uytterhoeven, magnus.damm
Cc: Neil Armstrong, Philipp Zabel, linux-renesas-soc@vger.kernel.org,
linux-phy@lists.infradead.org, linux-kernel@vger.kernel.org,
Prabhakar Mahadev Lad
In-Reply-To: <75976eb6-5837-4229-9faa-c77e058d1cba@tuxon.dev>
Hi Claudiu,
> -----Original Message-----
> From: Claudiu Beznea <claudiu.beznea@tuxon.dev>
> Sent: 15 June 2026 12:44
> Subject: Re: [PATCH 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled
> VBUS regulator
>
>
>
> On 6/15/26 13:22, Biju Das wrote:
> > Hi Claudiu,
> >
> >> -----Original Message-----
> >> From: Claudiu Beznea <claudiu.beznea@tuxon.dev>
> >> Sent: 15 June 2026 10:37
> >> Subject: Re: [PATCH 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix devm
> >> action registration for disabled VBUS regulator
> >>
> >> Hi, Biju,
> >>
> >> On 6/12/26 17:30, Biju wrote:
> >>> From: Biju Das <biju.das.jz@bp.renesas.com>
> >>>
> >>> devm_regulator_get_exclusive() initialises the regulator with
> >>> enable_count = 1, requiring the consumer to disable it before release.
> >>>
> >>> Previously, the devm disable action was only registered when the
> >>> regulator was explicitly enabled, causing the cleanup path to skip
> >>> decrementing enable_count on device removal when the regulator was
> >>> left disabled.
> >>>
> >>> Fix this by always registering the devm disable action when the
> >>> regulator is enabled (checked via regulator_is_enabled()), covering
> >>> both the explicitly-enabled case and the initial state set by
> >>> devm_regulator_get_exclusive().
> >>>
> >>> This fixes WARN_ON enable count during regulator release.
> >>>
> >>> Fixes: 24843404efe4 ("phy: renesas: phy-rcar-gen3-usb2: Control VBUS
> >>> for RZ/G2L SoCs")
> >>> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
> >>
> >> The approach in this patch don't solve the problem, at least on RZ/G3S. See [1] for logs.
> >>
> >> I applied this patch on next-20260610:
> >>
> >> git log --oneline -2
> >> afe09f11d549 (HEAD) phy: renesas: phy-rcar-gen3-usb2: Fix devm action
> >> registration for disabled VBUS regulator
> >> abe651837cb3 (tag: next-20260610, linux-next/master) Add linux-next
> >> specific files for 20260610
> >>
> >> [1]
> >> https://github.com/claudiubeznea/logs/blob/2f1bab20407dfe6031385819ff
> >> eabfc4eac772bd/logs
> >
> > I have tested only with RZ/G3L host and I don't see the issue.
> > How can the issue be reproduced? It could be related to RZ/G3S.
>
> It's reproducible with this patch on G2L as well, please see
> https://github.com/claudiubeznea/logs/blob/0601044903b5ae714592db9770bc4ed31fd8bf84/logs.
>
> > I have executed the following tests and don't see any issue.
> > Can you please try the same tests on RZ/G3S?
>
> Try stressing it a bit, e.g. the following command trigger it on both G3S and G2L:
It is nothing related to stress, it is just enable_count issue.
Usb function increments the enable count of regulator, which it never decrement
Leading to WARN_ON(enable_count) during unbind.
>
> cnt=300; while [ $cnt -ge 0 ]; do echo 11c40000.usbphy-ctrl > unbind ; echo 11c40000.usbphy-ctrl > bind ;
> cnt=$((cnt-1)); done
>
> Same command could be executed for other USB drivers.
>
> > Is unbind/bind ever worked on RZ?G3S previously?
>
> In the same way it works on G2L: functionality is OK, these stack traces are displayed as on any other
> RZ/G2L based SoCs.
I have identified the issue, it is USB function related.
I am investigating the fix, which will fix for all platforms.
Cgeers,
Biju
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: phy: qcom,usb-hs-phy: add qcom,vendor-init-seq
From: me @ 2026-06-15 12:17 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Konrad Dybcio, github.com, linux-phy, devicetree, linux-arm-msm,
Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson
In-Reply-To: <tknuizddyhfcyywmm36v4ok6idgpxridgur5qbowvmwhcbve5o@bp3z46gsfvlk>
On 2026-06-12 02:25, Dmitry Baryshkov wrote:
> On Thu, Jun 11, 2026 at 12:39:45PM +0200, Konrad Dybcio wrote:
>> On 6/4/26 1:02 AM, Dmitry Baryshkov wrote:
>> > On Wed, Jun 03, 2026 at 06:09:18PM +0200, me@herrie.org wrote:
>> >> On 2026-06-03 15:57, Dmitry Baryshkov wrote:
>> >>> On Wed, Jun 03, 2026 at 07:48:08AM +0200, Herman van Hazendonk wrote:
>> >>>> Add an optional "qcom,vendor-init-seq" property carrying raw ULPI
>> >>>> (address, value) pairs that are written after PHY reset.
>> >>>>
>> >>>> Unlike the existing "qcom,init-seq" property, the address field is
>> >>>> NOT offset by ULPI_EXT_VENDOR_SPECIFIC, so the new property can
>> >>>> reach the standard ULPI vendor register range (0x30-0x3f). MSM8x60-
>> >>>> class hardware needs this range to programme pre-emphasis, HS driver
>> >>>> slope and CDR auto-reset bits the legacy msm_otg driver used to set
>> >>>> via platform data.
>> >>>
>> >>> Are those register writes specific to the device or to the whole
>> >>> platform? In the latter case please extend the driver to write them.
>> >>
>> >> Looking at every MSM8x60 reference kernel I could find (Qualcomm's own
>> >> msm8x60 board, HP TouchPad / APQ8060, and some HTC/Saumsung MSM8660
>> >> devices), the writes split into two groups:
>> >>
>> >> Platform-level (same across all MSM8x60 hardware):
>> >> - reg 0x36 bits 1+2: CDR auto-reset disabled, SE1 gating disabled
>> >> - reg 0x32 bits [5:4]: pre-emphasis at 20%
>> >>
>> >> Board-specific:
>> >> - reg 0x32 bits [3:0]: HS driver slope — HP TouchPad uses 5, HTC
>> >> devices use 1. This clearly depends on board layout (trace length,
>> >> connector loading, etc.).
>> >>
>> >> So the platform-level writes should move unconditionally into the driver
>> >> behind a match-data flag for the MSM8x60-class compatible, and only the
>> >> HS driver slope value belongs in DT.
>> >
>> > Looks like it. Please hardcode the value for your platform in the driver
>> > (with the comment), meanwhile we can try looking up the actual values.
>>
>> Do we have the values for a MTP/QRD (or whatever they used to be
>> called
>> back then..), like we would usually put in there?
>
> As far as I can understand msm-3.0 and msm-3.4 most of the boards were
> writing 0 here (although it might have been unexpected). None of the
> board files set the hsdrvslope value (which means 0).
>
> Please correct me if I'm wrong. I see that for tenderloin kernels
> change
> that to 0x5, but I can't find a sensible commit message.
>
> I could not find the documentation for vendor ULPI registers for those
> chips, so I don't think we can identify, how to make sense of those
> values. In such a case and having different board-specific values, we
> don't have a better option than having a qcom,hsdrvslope (or similarly
> named) property in DT.
Dmitry/Konrad,
The bit-level meaning *is* documented byte-for-byte across
every MSM8x60 downstream tree I could find: Code Aurora is the
canonical source:
arch/arm/mach-msm/include/mach/msm_hsusb_hw.h
#define ULPI_CONFIG_REG3 0x32
#define ULPI_DIGOUT_CTRL 0x36 /* on MSM7x30 /
MSM8x60 */
#define ULPI_CDR_AUTORESET (1 << 1)
#define ULPI_SE1_GATE (1 << 2)
#define ULPI_PRE_EMPHASIS_MASK (3 << 4)
#define ULPI_HSDRVSLOPE_MASK (0x0F)
reg 0x32 [5:4]: pre-emphasis level (00 disabled, 11 = 20%, 10 = 10%)
reg 0x32 [3:0]: HS driver slope
reg 0x36 bit 1: CDR auto-reset enable
reg 0x36 bit 2: SE1 gating enable
The legacy `msm72k_otg.c` semantics for the 0x36 bits are inverted:
setting the bit disables the function (see set_cdr_auto_reset() and
set_se1_gating()). Every MSM8x60 reference board sets both bits,
i.e. CDR auto-reset disabled + SE1 gating disabled.
Surveying every MSM8x60-class board file I can reach: Qualcomm's own
reference, Samsung, Sony, HTC, and HP: the platform-level values
are unanimous:
pre-emphasis = 20%
CDR auto-reset = disabled
SE1 gating = disabled
| Vendor / board | hsdrvslope |
| -----------------------------------------------|------------|
| Qualcomm reference (SURF / FFA / Fluid / | |
| Dragon / Fusion -- board-msm8x60.c) | unset (0) |
| Samsung Galaxy S2 family (Q1 / Celox / Dali / | |
| generic 8x60 MTP) | unset (0) |
| Sony MSM8660 (sony-kernel-msm8660) | unset (0) |
| HTC MSM8660 (shooter / holiday / pyramid / | |
| doubleshot / shooter_u / ruby) | 1 |
| HP TouchPad (board-tenderloin.c) | 5 |
So Qualcomm's own MTP, the closest thing to a reference platform we
have, leaves hsdrvslope at the silicon default (0). Two OEMs (HTC,
HP) override it to non-zero values that match their board layout.
Neither override has a commit message. HTC's value is buried in an
init_seq array, HP's appears as `.hsdrvslope = 0x05` in
board-tenderloin.c with no comment. I've kept TouchPad's 5 because
that's the value the device shipped with and our HS link is happy
with it; changing it risks regressing eye margin on the silicon we
still have to test against.
So the plan is exactly what you both already converged on:
1. Drop qcom,vendor-init-seq from the binding (this patch goes away
entirely).
2. In the driver, hardcode the three platform-level writes behind
the qcom,usb-hs-phy-msm8660 compatible match-data, with a
comment citing msm_hsusb_hw.h as the source for the bit names.
3. Add a single qcom,hs-drv-slope property (u8, 0..15) for the
board-varying value. TouchPad DT sets 5. Absent ⇒ leave silicon
default in place, matching Qualcomm/Samsung/Sony reference
behaviour.
I'll send the new v in that shape: single dt-bindings patch
(qcom,hs-drv-slope) plus the driver patch that hardcodes the platform
writes and consumes the new property.
Unless you have other suggestions?
Thanks,
Herman
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* RE: [PATCH 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled VBUS regulator
From: Biju Das @ 2026-06-15 12:30 UTC (permalink / raw)
To: Claudiu.Beznea, biju.das.au, Yoshihiro Shimoda, Vinod Koul,
Geert Uytterhoeven, magnus.damm
Cc: Neil Armstrong, Philipp Zabel, linux-renesas-soc@vger.kernel.org,
linux-phy@lists.infradead.org, linux-kernel@vger.kernel.org,
Prabhakar Mahadev Lad
In-Reply-To: <TY3PR01MB1134684AA984BDC881C8A640A86E62@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Hi Claudiu,
> -----Original Message-----
> From: Biju Das
> Sent: 15 June 2026 12:51
> Subject: RE: [PATCH 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled
> VBUS regulator
>
> Hi Claudiu,
>
> > -----Original Message-----
> > From: Claudiu Beznea <claudiu.beznea@tuxon.dev>
> > Sent: 15 June 2026 12:44
> > Subject: Re: [PATCH 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix devm
> > action registration for disabled VBUS regulator
> >
> >
> >
> > On 6/15/26 13:22, Biju Das wrote:
> > > Hi Claudiu,
> > >
> > >> -----Original Message-----
> > >> From: Claudiu Beznea <claudiu.beznea@tuxon.dev>
> > >> Sent: 15 June 2026 10:37
> > >> Subject: Re: [PATCH 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix
> > >> devm action registration for disabled VBUS regulator
> > >>
> > >> Hi, Biju,
> > >>
> > >> On 6/12/26 17:30, Biju wrote:
> > >>> From: Biju Das <biju.das.jz@bp.renesas.com>
> > >>>
> > >>> devm_regulator_get_exclusive() initialises the regulator with
> > >>> enable_count = 1, requiring the consumer to disable it before release.
> > >>>
> > >>> Previously, the devm disable action was only registered when the
> > >>> regulator was explicitly enabled, causing the cleanup path to skip
> > >>> decrementing enable_count on device removal when the regulator was
> > >>> left disabled.
> > >>>
> > >>> Fix this by always registering the devm disable action when the
> > >>> regulator is enabled (checked via regulator_is_enabled()),
> > >>> covering both the explicitly-enabled case and the initial state
> > >>> set by devm_regulator_get_exclusive().
> > >>>
> > >>> This fixes WARN_ON enable count during regulator release.
> > >>>
> > >>> Fixes: 24843404efe4 ("phy: renesas: phy-rcar-gen3-usb2: Control
> > >>> VBUS for RZ/G2L SoCs")
> > >>> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
> > >>
> > >> The approach in this patch don't solve the problem, at least on RZ/G3S. See [1] for logs.
> > >>
> > >> I applied this patch on next-20260610:
> > >>
> > >> git log --oneline -2
> > >> afe09f11d549 (HEAD) phy: renesas: phy-rcar-gen3-usb2: Fix devm
> > >> action registration for disabled VBUS regulator
> > >> abe651837cb3 (tag: next-20260610, linux-next/master) Add linux-next
> > >> specific files for 20260610
> > >>
> > >> [1]
> > >> https://github.com/claudiubeznea/logs/blob/2f1bab20407dfe6031385819
> > >> ff
> > >> eabfc4eac772bd/logs
> > >
> > > I have tested only with RZ/G3L host and I don't see the issue.
> > > How can the issue be reproduced? It could be related to RZ/G3S.
> >
> > It's reproducible with this patch on G2L as well, please see
> > https://github.com/claudiubeznea/logs/blob/0601044903b5ae714592db9770bc4ed31fd8bf84/logs.
> >
> > > I have executed the following tests and don't see any issue.
> > > Can you please try the same tests on RZ/G3S?
> >
> > Try stressing it a bit, e.g. the following command trigger it on both G3S and G2L:
>
> It is nothing related to stress, it is just enable_count issue.
> Usb function increments the enable count of regulator, which it never decrement Leading to
> WARN_ON(enable_count) during unbind.
>
> >
> > cnt=300; while [ $cnt -ge 0 ]; do echo 11c40000.usbphy-ctrl > unbind ;
> > echo 11c40000.usbphy-ctrl > bind ; cnt=$((cnt-1)); done
> >
> > Same command could be executed for other USB drivers.
> >
> > > Is unbind/bind ever worked on RZ?G3S previously?
> >
> > In the same way it works on G2L: functionality is OK, these stack
> > traces are displayed as on any other RZ/G2L based SoCs.
>
> I have identified the issue, it is USB function related.
>
> I am investigating the fix, which will fix for all platforms.
The issue you saw on RZ/G3S is
usbhs_platform_call(priv, hardware_exit, pdev) is called before
usbhsc_power_ctrl(priv, 0);
The former Nullify the PHY pointer and later does not call
phy_power_off(priv->phy) to decrement the regulator.
Cheers,
Biju
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* RE: [PATCH 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled VBUS regulator
From: Biju Das @ 2026-06-15 12:42 UTC (permalink / raw)
To: Claudiu.Beznea, biju.das.au, Yoshihiro Shimoda, Vinod Koul,
Geert Uytterhoeven, magnus.damm
Cc: Neil Armstrong, Philipp Zabel, linux-renesas-soc@vger.kernel.org,
linux-phy@lists.infradead.org, linux-kernel@vger.kernel.org,
Prabhakar Mahadev Lad, stable, Greg Kroah-Hartman
In-Reply-To: <2b794049-0c44-4390-a6cd-e5bde5c5f3ca@tuxon.dev>
Hi Claudiu,
+ stable <stable@kernel.org>
> -----Original Message-----
> From: Claudiu Beznea <claudiu.beznea@tuxon.dev>
> Sent: 15 June 2026 10:37
> Subject: Re: [PATCH 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled
> VBUS regulator
>
> Hi, Biju,
>
> On 6/12/26 17:30, Biju wrote:
> > From: Biju Das <biju.das.jz@bp.renesas.com>
> >
> > devm_regulator_get_exclusive() initialises the regulator with
> > enable_count = 1, requiring the consumer to disable it before release.
> >
> > Previously, the devm disable action was only registered when the
> > regulator was explicitly enabled, causing the cleanup path to skip
> > decrementing enable_count on device removal when the regulator was
> > left disabled.
> >
> > Fix this by always registering the devm disable action when the
> > regulator is enabled (checked via regulator_is_enabled()), covering
> > both the explicitly-enabled case and the initial state set by
> > devm_regulator_get_exclusive().
> >
> > This fixes WARN_ON enable count during regulator release.
> >
> > Fixes: 24843404efe4 ("phy: renesas: phy-rcar-gen3-usb2: Control VBUS
> > for RZ/G2L SoCs")
> > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
>
> The approach in this patch don't solve the problem, at least on RZ/G3S. See [1] for logs.
>
> I applied this patch on next-20260610:
>
> git log --oneline -2
> afe09f11d549 (HEAD) phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled VBUS
> regulator
> abe651837cb3 (tag: next-20260610, linux-next/master) Add linux-next specific files for 20260610
>
> [1]
> https://github.com/claudiubeznea/logs/blob/2f1bab20407dfe6031385819ffeabfc4eac772bd/logs
This issue is introduced by the commit
eb9ac779830b223584 ("usb: renesas_usbhs: Fix synchronous external abort on unbind")
WARN_ON(enable_count) is related to regulator imbalance during unbind/bind cycle.
The above commit changed the code flow from
usbhsc_power_ctrl(priv, 0);
usbhs_platform_call(priv, hardware_exit, pdev);
to
usbhs_platform_call(priv, hardware_exit, pdev);
usbhsc_power_ctrl(priv, 0);
The function usbhs_*_hardware_exit(struct platform_device *pdev) sets
priv->phy to NULL
and
usbhs_*_power_ctrl() has the below code and [1] is a dead code now after this commit.
if (!priv->phy)
return -ENODEV;
if (enable) {
retval = phy_init(priv->phy);
usbhs_bset(priv, SUSPMODE, SUSPM, SUSPM);
udelay(100); /* Wait for PLL to become stable */
if (!retval)
retval = phy_power_on(priv->phy);
} else {
[1]
usbhs_bset(priv, SUSPMODE, SUSPM, 0);
phy_power_off(priv->phy);
phy_exit(priv->phy);
}
Cheers,
Biju
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 1/3] dt-bindings: phy: nuvoton,ma35d1-usb2-phy: extend for dual-port OTG support
From: Rob Herring (Arm) @ 2026-06-15 13:40 UTC (permalink / raw)
To: Joey Lu
Cc: Hui-Ping Chen, Neil Armstrong, Conor Dooley, Vinod Koul,
devicetree, Catalin Marinas, linux-arm-kernel,
Krzysztof Kozlowski, linux-kernel, Joey Lu, Jacky Huang,
Arnd Bergmann, linux-phy, Shan-Chun Hung
In-Reply-To: <20260615054911.48821-2-a0987203069@gmail.com>
On Mon, 15 Jun 2026 13:49:09 +0800, Joey Lu wrote:
> The MA35D1 has two USB PHY ports managed by the same hardware block:
>
> - PHY0 (index 0): OTG port shared between the DWC2 gadget controller
> and EHCI0/OHCI0 host controllers. A hardware mux follows the USB
> ID pin automatically.
>
> - PHY1 (index 1): dedicated host-only port for EHCI1/OHCI1.
>
> Extend the existing binding to cover both ports:
>
> - The PHY node is now a child of the system-management syscon node
> with a reg property. The nuvoton,sys phandle and clocks
> properties are removed; the driver derives the regmap from its
> parent, and clock gating is owned by each individual USB controller.
>
> - #phy-cells changes from 0 to 1: the cell selects the PHY port.
>
> - Two optional board-tuning properties are added: nuvoton,rcalcode
> for per-port resistor trim and nuvoton,oc-active-high for
> over-current polarity.
>
> Signed-off-by: Joey Lu <a0987203069@gmail.com>
> ---
> .../bindings/phy/nuvoton,ma35d1-usb2-phy.yaml | 62 ++++++++++++++-----
> 1 file changed, 48 insertions(+), 14 deletions(-)
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/phy/nuvoton,ma35d1-usb2-phy.example.dtb: system-management@40460000 (nuvoton,ma35d1-reset): '#address-cells', '#size-cells', 'usb-phy@60' do not match any of the regexes: '^pinctrl-[0-9]+$'
from schema $id: http://devicetree.org/schemas/reset/nuvoton,ma35d1-reset.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/phy/nuvoton,ma35d1-usb2-phy.example.dtb: system-management@40460000 (nuvoton,ma35d1-reset): compatible: ['nuvoton,ma35d1-reset', 'syscon', 'simple-mfd'] is too long
from schema $id: http://devicetree.org/schemas/reset/nuvoton,ma35d1-reset.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/phy/nuvoton,ma35d1-usb2-phy.example.dtb: system-management@40460000 (nuvoton,ma35d1-reset): reg: [[0, 1078329344], [0, 512]] is too long
from schema $id: http://devicetree.org/schemas/reset/nuvoton,ma35d1-reset.yaml
doc reference errors (make refcheckdocs):
See https://patchwork.kernel.org/project/devicetree/patch/20260615054911.48821-2-a0987203069@gmail.com
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v1] phy: Add USB3 PHY support to Google Tensor SoC USB PHY driver
From: RD Babiera @ 2026-06-15 18:05 UTC (permalink / raw)
To: vkoul, peter.griffin, andre.draszik, tudor.ambarus, p.zabel,
neil.armstrong
Cc: badhri, linux-arm-kernel, linux-samsung-soc, linux-phy,
linux-kernel, RD Babiera
Add USB3 PHY support for the Google Tensor G5 USB PHY driver.
This patch adds functionality for the usb3_core and usb3_tca registers,
usb3 clock, and usb3 reset as defined in
google,lga-usb-phy.yaml.
Refactor the probe sequence to initialize the USB2 and USB3 PHYs, and then
initialize clocks and resets for both PHYs afterwards.
Refactor set_vbus_valid to reduce duplicated code.
Implement USB3 phy_ops for phy_init, phy_exit, and phy_power_on.
Signed-off-by: RD Babiera <rdbabiera@google.com>
---
drivers/phy/phy-google-usb.c | 350 +++++++++++++++++++++++++++++++----
1 file changed, 317 insertions(+), 33 deletions(-)
diff --git a/drivers/phy/phy-google-usb.c b/drivers/phy/phy-google-usb.c
index ab20bc20f19e..a23a9008b521 100644
--- a/drivers/phy/phy-google-usb.c
+++ b/drivers/phy/phy-google-usb.c
@@ -20,6 +20,7 @@
#include <linux/reset.h>
#include <linux/usb/typec_mux.h>
+/* USB_CFG_CSR */
#define USBCS_USB2PHY_CFG19_OFFSET 0x0
#define USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV GENMASK(19, 8)
@@ -28,11 +29,41 @@
#define USBCS_USB2PHY_CFG21_REF_FREQ_SEL GENMASK(15, 13)
#define USBCS_USB2PHY_CFG21_PHY_TX_DIG_BYPASS_SEL BIT(19)
+/* USBDP_TOP */
#define USBCS_PHY_CFG1_OFFSET 0x28
+#define USBCS_PHY_CFG1_PHY0_MPLLA_SSC_EN BIT(1)
+#define USBCS_PHY_CFG1_PHY0_SRAM_BYPASS_MODE GENMASK(11, 10)
+#define SRAM_BYPASS_MODE_BYPASS_FIRMWARE BIT(0)
+#define SRAM_BYPASS_MODE_BYPASS_CONTEXT BIT(1)
#define USBCS_PHY_CFG1_SYS_VBUSVALID BIT(17)
+#define USBDP_TOP_CFG_REG_OFFSET 0x44
+#define USBDP_TOP_CFG_REG_PMGT_REF_CLK_REQ_N BIT(0)
+
+#define PHY_POWER_CONFIG_REG1_OFFSET 0x48
+#define PHY_POWER_CONFIG_REG1_PG_MODE_EN BIT(1)
+#define PHY_POWER_CONFIG_REG1_UPCS_PIPE_CONFIG GENMASK(31, 14)
+#define UPCS_PIPE_CONFIG_ISO_CPM BIT(5)
+#define UPCS_PIPE_CONFIG_PG_MODE_STATIC BIT(6)
+#define UPCS_PIPE_CONFIG_LANE_RESET_NO_PG_EXIT BIT(9)
+
+/* USB3_TCA */
+#define TCA_INTR_STS_OFFSET 0x8
+#define TCA_INTR_STS_XA_ACT_EVT BIT(0)
+#define TCA_TCPC_OFFSET 0x14
+#define TCA_TCPC_MUX_CONTROL GENMASK(2, 0)
+#define TCA_TCPC_MUX_CONTROL_USB_ONLY 0x1
+#define TCA_TCPC_CONNECTOR_ORIENTATION BIT(3)
+#define TCA_TCPC_VALID BIT(4)
+#define TCA_PSTATE_0_OFFSET 0x50
+#define TCA_PSTATE_0_UPCS_LANE0_PHYSTATUS BIT(8)
+
+#define GPHY_TCA_DELAY_US 10
+#define GPHY_TCA_TIMEOUT_US 2500000
+
enum google_usb_phy_id {
GOOGLE_USB2_PHY,
+ GOOGLE_USB3_PHY,
GOOGLE_USB_PHY_NUM,
};
@@ -46,11 +77,50 @@ struct google_usb_phy_instance {
struct reset_control_bulk_data *rsts;
};
+struct google_usb_phy_config {
+ const char * const *clk_names;
+ unsigned int num_clks;
+ const char * const *rst_names;
+ unsigned int num_rsts;
+};
+
+static const char * const u2phy_clk_names[] = {
+ "usb2",
+ "usb2_apb",
+};
+static const char * const u3phy_clk_names[] = {
+ "usb3"
+};
+static const char * const u2phy_rst_names[] = {
+ "usb2",
+ "usb2_apb",
+};
+static const char * const u3phy_rst_names[] = {
+ "usb3"
+};
+
+static const struct google_usb_phy_config phy_configs[GOOGLE_USB_PHY_NUM] = {
+ [GOOGLE_USB2_PHY] = {
+ .clk_names = u2phy_clk_names,
+ .num_clks = ARRAY_SIZE(u2phy_clk_names),
+ .rst_names = u2phy_rst_names,
+ .num_rsts = ARRAY_SIZE(u2phy_rst_names),
+ },
+ [GOOGLE_USB3_PHY] = {
+ .clk_names = u3phy_clk_names,
+ .num_clks = ARRAY_SIZE(u3phy_clk_names),
+ .rst_names = u3phy_rst_names,
+ .num_rsts = ARRAY_SIZE(u3phy_rst_names),
+ },
+};
+
struct google_usb_phy {
struct device *dev;
struct regmap *usb_cfg_regmap;
unsigned int usb2_cfg_offset;
void __iomem *usbdp_top_base;
+ void __iomem *usb3_core_base;
+ void __iomem *usb3_tca_base;
struct google_usb_phy_instance *insts;
/*
* Protect phy registers from concurrent access, specifically via
@@ -65,15 +135,79 @@ static void set_vbus_valid(struct google_usb_phy *gphy)
{
u32 reg;
- if (gphy->orientation == TYPEC_ORIENTATION_NONE) {
- reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+ reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+ if (gphy->orientation == TYPEC_ORIENTATION_NONE)
reg &= ~USBCS_PHY_CFG1_SYS_VBUSVALID;
- writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
- } else {
- reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+ else
reg |= USBCS_PHY_CFG1_SYS_VBUSVALID;
- writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
- }
+ writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+}
+
+static void set_sram_bypass(struct google_usb_phy *gphy, u32 bypass)
+{
+ u32 reg;
+
+ reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+ reg &= ~USBCS_PHY_CFG1_PHY0_SRAM_BYPASS_MODE;
+ reg |= FIELD_PREP(USBCS_PHY_CFG1_PHY0_SRAM_BYPASS_MODE, bypass);
+ writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+}
+
+static void set_pmgt_ref_clk_req_n(struct google_usb_phy *gphy, bool resume)
+{
+ u32 reg;
+
+ reg = readl(gphy->usbdp_top_base + USBDP_TOP_CFG_REG_OFFSET);
+ if (resume)
+ reg |= USBDP_TOP_CFG_REG_PMGT_REF_CLK_REQ_N;
+ else
+ reg &= ~USBDP_TOP_CFG_REG_PMGT_REF_CLK_REQ_N;
+ writel(reg, gphy->usbdp_top_base + USBDP_TOP_CFG_REG_OFFSET);
+}
+
+static int wait_tca_xa_ack(struct google_usb_phy *gphy)
+{
+ int ret;
+ u32 reg;
+
+ ret = readl_poll_timeout(gphy->usb3_tca_base + TCA_INTR_STS_OFFSET,
+ reg, !!(reg & TCA_INTR_STS_XA_ACT_EVT),
+ GPHY_TCA_DELAY_US, GPHY_TCA_TIMEOUT_US);
+ if (ret)
+ dev_err(gphy->dev, "tca xa_ack timeout, ret=%d", ret);
+
+ return ret;
+}
+
+static int program_tca_locked(struct google_usb_phy *gphy)
+ __must_hold(&gphy->phy_mutex)
+{
+ int ret;
+ u32 reg;
+
+ reg = readl(gphy->usb3_tca_base + TCA_INTR_STS_OFFSET);
+ writel(reg, gphy->usb3_tca_base + TCA_INTR_STS_OFFSET);
+
+ reg = readl(gphy->usb3_tca_base + TCA_TCPC_OFFSET);
+ reg &= ~TCA_TCPC_MUX_CONTROL;
+ reg |= FIELD_PREP(TCA_TCPC_MUX_CONTROL, TCA_TCPC_MUX_CONTROL_USB_ONLY);
+ if (gphy->orientation == TYPEC_ORIENTATION_REVERSE)
+ reg |= TCA_TCPC_CONNECTOR_ORIENTATION;
+ else
+ reg &= ~TCA_TCPC_CONNECTOR_ORIENTATION;
+ reg |= TCA_TCPC_VALID;
+ writel(reg, gphy->usb3_tca_base + TCA_TCPC_OFFSET);
+
+ ret = wait_tca_xa_ack(gphy);
+ dev_dbg(gphy->dev, "TCA switch %s, mux %lu, orientation %s",
+ ret ? "failed" : "success",
+ FIELD_GET(TCA_TCPC_MUX_CONTROL, reg),
+ FIELD_GET(TCA_TCPC_CONNECTOR_ORIENTATION, reg) ? "reverse" : "normal");
+
+ reg = readl(gphy->usb3_tca_base + TCA_INTR_STS_OFFSET);
+ writel(reg, gphy->usb3_tca_base + TCA_INTR_STS_OFFSET);
+
+ return ret;
}
static int google_usb_set_orientation(struct typec_switch_dev *sw,
@@ -161,6 +295,103 @@ static const struct phy_ops google_usb2_phy_ops = {
.exit = google_usb2_phy_exit,
};
+static int google_usb3_phy_init(struct phy *_phy)
+{
+ struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
+ struct google_usb_phy *gphy = inst->parent;
+ int ret = 0;
+ u32 reg;
+
+ dev_dbg(gphy->dev, "initializing usb3 phy\n");
+
+ guard(mutex)(&gphy->phy_mutex);
+
+ reg = readl(gphy->usbdp_top_base + PHY_POWER_CONFIG_REG1_OFFSET);
+ reg |= PHY_POWER_CONFIG_REG1_PG_MODE_EN;
+ reg &= ~PHY_POWER_CONFIG_REG1_UPCS_PIPE_CONFIG;
+ reg |= FIELD_PREP(PHY_POWER_CONFIG_REG1_UPCS_PIPE_CONFIG,
+ (UPCS_PIPE_CONFIG_ISO_CPM |
+ UPCS_PIPE_CONFIG_PG_MODE_STATIC |
+ UPCS_PIPE_CONFIG_LANE_RESET_NO_PG_EXIT));
+ writel(reg, gphy->usbdp_top_base + PHY_POWER_CONFIG_REG1_OFFSET);
+
+ set_vbus_valid(gphy);
+
+ reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+ reg |= USBCS_PHY_CFG1_PHY0_MPLLA_SSC_EN;
+ writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+
+ set_sram_bypass(gphy, SRAM_BYPASS_MODE_BYPASS_FIRMWARE |
+ SRAM_BYPASS_MODE_BYPASS_CONTEXT);
+ set_pmgt_ref_clk_req_n(gphy, true);
+
+ ret = clk_bulk_prepare_enable(inst->num_clks, inst->clks);
+ if (ret)
+ return ret;
+
+ ret = reset_control_bulk_deassert(inst->num_rsts, inst->rsts);
+ if (ret)
+ goto disable_clocks;
+
+ ret = readl_poll_timeout(gphy->usb3_tca_base + TCA_PSTATE_0_OFFSET,
+ reg, !(reg & TCA_PSTATE_0_UPCS_LANE0_PHYSTATUS),
+ GPHY_TCA_DELAY_US, GPHY_TCA_TIMEOUT_US);
+ if (ret) {
+ dev_err(gphy->dev, "wait for lane0 phystatus timed out");
+ goto assert_resets;
+ }
+
+ return 0;
+
+assert_resets:
+ reset_control_bulk_assert(inst->num_rsts, inst->rsts);
+disable_clocks:
+ clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
+ return ret;
+}
+
+static int google_usb3_phy_exit(struct phy *_phy)
+{
+ struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
+ struct google_usb_phy *gphy = inst->parent;
+
+ dev_dbg(gphy->dev, "exiting usb3 phy\n");
+
+ guard(mutex)(&gphy->phy_mutex);
+
+ set_pmgt_ref_clk_req_n(gphy, false);
+ reset_control_bulk_assert(inst->num_rsts, inst->rsts);
+ clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
+
+ return 0;
+}
+
+static int google_usb3_phy_power_on(struct phy *_phy)
+{
+ struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
+ struct google_usb_phy *gphy = inst->parent;
+ int ret;
+
+ dev_dbg(gphy->dev, "power on usb3 phy\n");
+
+ guard(mutex)(&gphy->phy_mutex);
+ ret = wait_tca_xa_ack(gphy);
+ if (ret) {
+ dev_err(gphy->dev, "PoR->NC transition timeout");
+ return ret;
+ }
+
+ ret = program_tca_locked(gphy);
+
+ return ret;
+}
+
+static const struct phy_ops google_usb3_phy_ops = {
+ .init = google_usb3_phy_init,
+ .exit = google_usb3_phy_exit,
+ .power_on = google_usb3_phy_power_on,
+};
+
static struct phy *google_usb_phy_xlate(struct device *dev,
const struct of_phandle_args *args)
{
@@ -173,14 +404,61 @@ static struct phy *google_usb_phy_xlate(struct device *dev,
return gphy->insts[args->args[0]].phy;
}
+static int google_usb_phy_parse_clocks(struct google_usb_phy *gphy)
+{
+ struct device *dev = gphy->dev;
+ int id, i, ret;
+
+ for (id = 0; id < GOOGLE_USB_PHY_NUM; id++) {
+ const struct google_usb_phy_config *cfg = &phy_configs[id];
+ struct google_usb_phy_instance *inst = &gphy->insts[id];
+
+ inst->num_clks = cfg->num_clks;
+ inst->clks = devm_kcalloc(dev, inst->num_clks, sizeof(*inst->clks), GFP_KERNEL);
+ if (!inst->clks)
+ return -ENOMEM;
+
+ for (i = 0; i < inst->num_clks; i++)
+ inst->clks[i].id = cfg->clk_names[i];
+
+ ret = devm_clk_bulk_get(dev, inst->num_clks, inst->clks);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to get phy%d clks\n", id);
+ }
+
+ return 0;
+}
+
+static int google_usb_phy_parse_resets(struct google_usb_phy *gphy)
+{
+ struct device *dev = gphy->dev;
+ int id, i, ret;
+
+ for (id = 0; id < GOOGLE_USB_PHY_NUM; id++) {
+ const struct google_usb_phy_config *cfg = &phy_configs[id];
+ struct google_usb_phy_instance *inst = &gphy->insts[id];
+
+ inst->num_rsts = cfg->num_rsts;
+ inst->rsts = devm_kcalloc(dev, inst->num_rsts, sizeof(*inst->rsts), GFP_KERNEL);
+ if (!inst->rsts)
+ return -ENOMEM;
+
+ for (i = 0; i < inst->num_rsts; i++)
+ inst->rsts[i].id = cfg->rst_names[i];
+ ret = devm_reset_control_bulk_get_exclusive(dev, inst->num_rsts, inst->rsts);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to get phy%d resets\n", id);
+ }
+
+ return 0;
+}
+
static int google_usb_phy_probe(struct platform_device *pdev)
{
struct typec_switch_desc sw_desc = { };
- struct google_usb_phy_instance *inst;
struct phy_provider *phy_provider;
struct device *dev = &pdev->dev;
struct google_usb_phy *gphy;
- struct phy *phy;
u32 args[1];
int ret;
@@ -212,39 +490,45 @@ static int google_usb_phy_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(gphy->usbdp_top_base),
"invalid usbdp top\n");
+ gphy->usb3_core_base = devm_platform_ioremap_resource_byname(pdev,
+ "usb3_core");
+ if (IS_ERR(gphy->usb3_core_base))
+ return dev_err_probe(dev, PTR_ERR(gphy->usb3_core_base),
+ "invalid usb3 core\n");
+
+ gphy->usb3_tca_base = devm_platform_ioremap_resource_byname(pdev,
+ "usb3_tca");
+ if (IS_ERR(gphy->usb3_tca_base))
+ return dev_err_probe(dev, PTR_ERR(gphy->usb3_tca_base),
+ "invalid usb3 tca\n");
+
gphy->insts = devm_kcalloc(dev, GOOGLE_USB_PHY_NUM, sizeof(*gphy->insts), GFP_KERNEL);
if (!gphy->insts)
return -ENOMEM;
- inst = &gphy->insts[GOOGLE_USB2_PHY];
- inst->parent = gphy;
- inst->index = GOOGLE_USB2_PHY;
- phy = devm_phy_create(dev, NULL, &google_usb2_phy_ops);
- if (IS_ERR(phy))
- return dev_err_probe(dev, PTR_ERR(phy),
+ gphy->insts[GOOGLE_USB2_PHY].phy = devm_phy_create(dev, NULL, &google_usb2_phy_ops);
+ gphy->insts[GOOGLE_USB2_PHY].index = GOOGLE_USB2_PHY;
+ gphy->insts[GOOGLE_USB2_PHY].parent = gphy;
+ if (IS_ERR(gphy->insts[GOOGLE_USB2_PHY].phy))
+ return dev_err_probe(dev, PTR_ERR(gphy->insts[GOOGLE_USB2_PHY].phy),
"failed to create usb2 phy instance\n");
- inst->phy = phy;
- phy_set_drvdata(phy, inst);
+ phy_set_drvdata(gphy->insts[GOOGLE_USB2_PHY].phy, &gphy->insts[GOOGLE_USB2_PHY]);
- inst->num_clks = 2;
- inst->clks = devm_kcalloc(dev, inst->num_clks, sizeof(*inst->clks), GFP_KERNEL);
- if (!inst->clks)
- return -ENOMEM;
- inst->clks[0].id = "usb2";
- inst->clks[1].id = "usb2_apb";
- ret = devm_clk_bulk_get(dev, inst->num_clks, inst->clks);
+ gphy->insts[GOOGLE_USB3_PHY].phy = devm_phy_create(dev, NULL, &google_usb3_phy_ops);
+ gphy->insts[GOOGLE_USB3_PHY].index = GOOGLE_USB3_PHY;
+ gphy->insts[GOOGLE_USB3_PHY].parent = gphy;
+ if (IS_ERR(gphy->insts[GOOGLE_USB3_PHY].phy))
+ return dev_err_probe(dev, PTR_ERR(gphy->insts[GOOGLE_USB3_PHY].phy),
+ "failed to create usb3 phy instance\n");
+ phy_set_drvdata(gphy->insts[GOOGLE_USB3_PHY].phy, &gphy->insts[GOOGLE_USB3_PHY]);
+
+ ret = google_usb_phy_parse_clocks(gphy);
if (ret)
- return dev_err_probe(dev, ret, "failed to get u2 phy clks\n");
+ return ret;
- inst->num_rsts = 2;
- inst->rsts = devm_kcalloc(dev, inst->num_rsts, sizeof(*inst->rsts), GFP_KERNEL);
- if (!inst->rsts)
- return -ENOMEM;
- inst->rsts[0].id = "usb2";
- inst->rsts[1].id = "usb2_apb";
- ret = devm_reset_control_bulk_get_exclusive(dev, inst->num_rsts, inst->rsts);
+ ret = google_usb_phy_parse_resets(gphy);
if (ret)
- return dev_err_probe(dev, ret, "failed to get u2 phy resets\n");
+ return ret;
phy_provider = devm_of_phy_provider_register(dev, google_usb_phy_xlate);
if (IS_ERR(phy_provider))
base-commit: 2ace2e949979b82f82f12dd76d7c5a6145246ca3
--
2.54.0.1189.g8c84645362-goog
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* Re: [PATCH v1] phy: Add USB3 PHY support to Google Tensor SoC USB PHY driver
From: sashiko-bot @ 2026-06-15 18:17 UTC (permalink / raw)
To: RD Babiera; +Cc: olteanv, linux-phy, neil.armstrong, vkoul
In-Reply-To: <20260615180556.4048184-2-rdbabiera@google.com>
Thank you for your contribution! Sashiko AI review found 7 potential issue(s) to consider:
New issues:
- [High] Missing hardware state update for the USB3 TCA switch when Type-C orientation changes.
- [High] google_usb3_phy_power_on() times out on subsequent calls due to cleared Power-on-Reset interrupt status.
- [High] Asymmetric hardware teardown sequence in google_usb3_phy_exit().
- [Medium] Mixing scope-based cleanup (guard) with goto-based error handling in google_usb3_phy_init().
- [Medium] Missing cleanup of pmgt_ref_clk_req_n hardware state on error paths in google_usb3_phy_init().
- [Medium] The usb3_core memory region is mapped as a mandatory resource but is never used.
Pre-existing issues:
- [High] TOCTOU race with pm_runtime_suspended() leading to unsafe MMIO access.
--
commit ab00032aabbed532e8e0ec1ad61b86eb2f271b6d
Author: RD Babiera <rdbabiera@google.com>
phy: Add USB3 PHY support to Google Tensor SoC USB PHY driver
This commit adds USB3 PHY support to the Google Tensor G5 USB PHY driver.
It introduces functionality for the usb3_core and usb3_tca registers, clocks,
and resets, and implements the USB3 phy_ops for init, exit, and power_on.
> diff --git a/drivers/phy/phy-google-usb.c b/drivers/phy/phy-google-usb.c
> --- a/drivers/phy/phy-google-usb.c
> +++ b/drivers/phy/phy-google-usb.c
[ ... ]
> @@ -65,15 +135,79 @@ static void set_vbus_valid(struct google_usb_phy *gphy)
[ ... ]
> +static int program_tca_locked(struct google_usb_phy *gphy)
> + __must_hold(&gphy->phy_mutex)
> +{
[ ... ]
> +}
>
> static int google_usb_set_orientation(struct typec_switch_dev *sw,
[Severity: High]
Does this missing update cause USB3 signal routing failures on orientation
changes?
When the Type-C orientation changes, google_usb_set_orientation() updates
the software state and calls set_vbus_valid(gphy). While this was sufficient
for USB2, it doesn't seem to reprogram the newly added USB3 TCA hardware
multiplexer.
If the orientation flips while the USB3 PHY is active, will the hardware
state miss the update because program_tca_locked() is not invoked, leaving
the TCA_TCPC_CONNECTOR_ORIENTATION bit stale?
[Severity: High]
This is a pre-existing issue, but does the lockless check of
pm_runtime_suspended() create a TOCTOU race condition?
In google_usb_set_orientation():
if (pm_runtime_suspended(gphy->dev))
return 0;
guard(mutex)(&gphy->phy_mutex);
set_vbus_valid(gphy);
Because no PM runtime reference is acquired (like pm_runtime_get_sync()),
can the device be suspended by the PM core immediately after the check
returns false? This would cause the subsequent register access in
set_vbus_valid() to trigger a synchronous external abort on suspended
hardware.
> @@ -161,6 +295,103 @@ static const struct phy_ops google_usb2_phy_ops = {
[ ... ]
> +static int google_usb3_phy_init(struct phy *_phy)
> +{
[ ... ]
> + guard(mutex)(&gphy->phy_mutex);
[ ... ]
> + set_pmgt_ref_clk_req_n(gphy, true);
> +
> + ret = clk_bulk_prepare_enable(inst->num_clks, inst->clks);
> + if (ret)
> + return ret;
> +
> + ret = reset_control_bulk_deassert(inst->num_rsts, inst->rsts);
> + if (ret)
> + goto disable_clocks;
> +
> + ret = readl_poll_timeout(gphy->usb3_tca_base + TCA_PSTATE_0_OFFSET,
> + reg, !(reg & TCA_PSTATE_0_UPCS_LANE0_PHYSTATUS),
> + GPHY_TCA_DELAY_US, GPHY_TCA_TIMEOUT_US);
> + if (ret) {
> + dev_err(gphy->dev, "wait for lane0 phystatus timed out");
> + goto assert_resets;
> + }
> +
> + return 0;
> +
> +assert_resets:
> + reset_control_bulk_assert(inst->num_rsts, inst->rsts);
> +disable_clocks:
> + clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
> + return ret;
> +}
[Severity: Medium]
Is it safe to mix goto-based error handling with scope-based cleanup here?
According to the cleanup subsystem documentation, usage of goto and cleanup
helpers like guard(mutex) should never be mixed in the same function. Can
this create confusing execution order and resource ownership?
[Severity: Medium]
Are we missing a step to revert the hardware clock request on the error path?
Earlier in this function, the reference clock request is enabled via
set_pmgt_ref_clk_req_n(). If clk_bulk_prepare_enable() or
reset_control_bulk_deassert() fail, the error paths disable the clocks
and assert resets, but they don't seem to call set_pmgt_ref_clk_req_n()
to disable the clock request. Will this leave the hardware clock request
permanently asserted on failure?
> +static int google_usb3_phy_exit(struct phy *_phy)
> +{
[ ... ]
> + set_pmgt_ref_clk_req_n(gphy, false);
> + reset_control_bulk_assert(inst->num_rsts, inst->rsts);
> + clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
> +
> + return 0;
> +}
[Severity: High]
Is this hardware teardown sequence in the correct order?
In google_usb3_phy_init(), the sequence is:
1) Request reference clock
2) Enable bus clocks
3) Deassert resets
Here in the exit function, the reference clock request is released first,
then resets are asserted, and bus clocks are disabled last. Could releasing
the reference clock while the PHY is still active and out of reset lead to
bus faults and system lockups?
> +static int google_usb3_phy_power_on(struct phy *_phy)
> +{
[ ... ]
> + ret = wait_tca_xa_ack(gphy);
> + if (ret) {
> + dev_err(gphy->dev, "PoR->NC transition timeout");
> + return ret;
> + }
> +
> + ret = program_tca_locked(gphy);
> +
> + return ret;
> +}
[Severity: High]
Will this unconditionally time out on subsequent power-on calls?
This function waits for a PoR->NC transition by checking the
TCA_INTR_STS_XA_ACT_EVT bit. However, this interrupt bit is explicitly
cleared at the end of program_tca_locked().
If the PHY framework calls phy_power_on() sequentially (for example,
during PM runtime resume) without a preceding phy_init() to trigger a
physical reset, the bit will remain 0. Does this cause wait_tca_xa_ack()
to inevitably time out after 2.5 seconds?
> @@ -212,39 +490,45 @@ static int google_usb_phy_probe(struct platform_device *pdev)
[ ... ]
> + gphy->usb3_core_base = devm_platform_ioremap_resource_byname(pdev,
> + "usb3_core");
> + if (IS_ERR(gphy->usb3_core_base))
> + return dev_err_probe(dev, PTR_ERR(gphy->usb3_core_base),
> + "invalid usb3 core\n");
> +
[Severity: Medium]
Is the usb3_core memory region actually used anywhere in the driver?
This maps the usb3_core resource and aborts the probe if it is missing,
but the resulting gphy->usb3_core_base pointer doesn't appear to be
referenced later. Could this introduce an unnecessary strict dependency
that breaks the probe on older Device Trees lacking this resource?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260615180556.4048184-2-rdbabiera@google.com?part=1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH] phy: broadcom: brcm-usb: unwind late probe failures
From: Justin Chen @ 2026-06-15 18:22 UTC (permalink / raw)
To: Pengpeng Hou, Al Cooper, Broadcom internal kernel review list,
Vinod Koul, Neil Armstrong, linux-kernel, linux-phy
In-Reply-To: <20260615070123.51155-1-pengpeng@iscas.ac.cn>
On 6/15/26 12:01 AM, Pengpeng Hou wrote:
> brcm_usb_phy_probe() registers a PM notifier and may create a sysfs group
> before registering the OF PHY provider. If provider registration fails,
> probe returns the error with those resources still active.
>
> Track which optional resources were installed and remove them on the late
> provider-registration failure path. Use the same state in remove() so
> cleanup matches probe progress.
>
> Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Reviewed-by: Justin Chen <justin.chen@broadcom.com>
--
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: Krishna Kurapati @ 2026-06-15 19:02 UTC (permalink / raw)
To: Krzysztof Kozlowski, 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
In-Reply-To: <20260527-lucky-porcelain-bullfrog-185f1d@quoll>
On 5/27/2026 3:16 PM, Krzysztof Kozlowski wrote:
> 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.
>
Ok, will separate out for Shikra and keep only two for Talos.
>>
>> 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.
>
The resets needed on Shikra are:
GCC_USB3PHY_PHY_PRIM_SP0_BCR
GCC_USB3_DP_PHY_PRIM_BCR
GCC_USB3_PHY_PRIM_SP0_BCR
Hence named the third one as "phy".
Regards,
Krishna,
--
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: Krishna Kurapati @ 2026-06-15 19:03 UTC (permalink / raw)
To: Xiangxu Yin
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
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
In-Reply-To: <d2098b36-c514-44e8-99b9-2213c4d52752@oss.qualcomm.com>
On 5/27/2026 11:57 AM, Xiangxu Yin wrote:
>
> 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.
>
>
ACK, will create a new match_data cfg for Shikra instead of reusing the
talos one.
Regards,
Krishna,
>> 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
* Re: [PATCH v1] phy: Add USB3 PHY support to Google Tensor SoC USB PHY driver
From: RD Babiera @ 2026-06-15 21:53 UTC (permalink / raw)
To: sashiko-reviews; +Cc: olteanv, linux-phy, neil.armstrong, vkoul
In-Reply-To: <20260615181706.37CEE1F000E9@smtp.kernel.org>
On Mon, Jun 15, 2026 at 11:17 AM <sashiko-bot@kernel.org> wrote:
> [Severity: High]
> Does this missing update cause USB3 signal routing failures on orientation
> changes?
>
> When the Type-C orientation changes, google_usb_set_orientation() updates
> the software state and calls set_vbus_valid(gphy). While this was sufficient
> for USB2, it doesn't seem to reprogram the newly added USB3 TCA hardware
> multiplexer.
>
> If the orientation flips while the USB3 PHY is active, will the hardware
> state miss the update because program_tca_locked() is not invoked, leaving
> the TCA_TCPC_CONNECTOR_ORIENTATION bit stale?
program_tca_locked should be called if the phy_init and phy_power on sequence
are completed and an orientation change is made. I'll add an internal phy state
enum to indicate when the operation is safe and check in
google_usb_set_orientation.
> [Severity: Medium]
> Is it safe to mix goto-based error handling with scope-based cleanup here?
>
> According to the cleanup subsystem documentation, usage of goto and cleanup
> helpers like guard(mutex) should never be mixed in the same function. Can
> this create confusing execution order and resource ownership?
I'll remove the go-to statements here.
> [Severity: Medium]
> Are we missing a step to revert the hardware clock request on the error path?
set_pmgt_ref_clk_req_n() will reset on the error path as the HW is powered down
and powered on, so there is no concern here.
> [Severity: High]
> Is this hardware teardown sequence in the correct order?
The teardown sequence is consistent with our requirements, no
concern on our end.
> [Severity: High]
> Will this unconditionally time out on subsequent power-on calls?
phy-core documentation indicates that power_on is called after phy_init,
and the power_on callback will only be called when the power_on count is 0.
In addition, the aforementioned internal phy state will prevent an unnecessary
power-on call if the PHY had not been torn down yet.
> [Severity: Medium]
> Is the usb3_core memory region actually used anywhere in the driver?
>
> This maps the usb3_core resource and aborts the probe if it is missing,
> but the resulting gphy->usb3_core_base pointer doesn't appear to be
> referenced later. Could this introduce an unnecessary strict dependency
> that breaks the probe on older Device Trees lacking this resource?
This currently isn't being used in the driver, so it will be fine to
remove it for now.
Best,
RD
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: phy: qcom,usb-hs-phy: add qcom,vendor-init-seq
From: Dmitry Baryshkov @ 2026-06-16 0:24 UTC (permalink / raw)
To: github.com
Cc: Konrad Dybcio, linux-phy, devicetree, linux-arm-msm, Vinod Koul,
Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson
In-Reply-To: <0298e09a5b4497910c226269daa2586b@herrie.org>
On Mon, Jun 15, 2026 at 02:17:08PM +0200, me@herrie.org wrote:
> On 2026-06-12 02:25, Dmitry Baryshkov wrote:
> > On Thu, Jun 11, 2026 at 12:39:45PM +0200, Konrad Dybcio wrote:
> > > On 6/4/26 1:02 AM, Dmitry Baryshkov wrote:
> > > > On Wed, Jun 03, 2026 at 06:09:18PM +0200, me@herrie.org wrote:
> > > >> On 2026-06-03 15:57, Dmitry Baryshkov wrote:
> > > >>> On Wed, Jun 03, 2026 at 07:48:08AM +0200, Herman van Hazendonk wrote:
> > > >>>> Add an optional "qcom,vendor-init-seq" property carrying raw ULPI
> > > >>>> (address, value) pairs that are written after PHY reset.
> > > >>>>
> > > >>>> Unlike the existing "qcom,init-seq" property, the address field is
> > > >>>> NOT offset by ULPI_EXT_VENDOR_SPECIFIC, so the new property can
> > > >>>> reach the standard ULPI vendor register range (0x30-0x3f). MSM8x60-
> > > >>>> class hardware needs this range to programme pre-emphasis, HS driver
> > > >>>> slope and CDR auto-reset bits the legacy msm_otg driver used to set
> > > >>>> via platform data.
> > > >>>
> > > >>> Are those register writes specific to the device or to the whole
> > > >>> platform? In the latter case please extend the driver to write them.
> > > >>
> > > >> Looking at every MSM8x60 reference kernel I could find (Qualcomm's own
> > > >> msm8x60 board, HP TouchPad / APQ8060, and some HTC/Saumsung MSM8660
> > > >> devices), the writes split into two groups:
> > > >>
> > > >> Platform-level (same across all MSM8x60 hardware):
> > > >> - reg 0x36 bits 1+2: CDR auto-reset disabled, SE1 gating disabled
> > > >> - reg 0x32 bits [5:4]: pre-emphasis at 20%
> > > >>
> > > >> Board-specific:
> > > >> - reg 0x32 bits [3:0]: HS driver slope — HP TouchPad uses 5, HTC
> > > >> devices use 1. This clearly depends on board layout (trace length,
> > > >> connector loading, etc.).
> > > >>
> > > >> So the platform-level writes should move unconditionally into the driver
> > > >> behind a match-data flag for the MSM8x60-class compatible, and only the
> > > >> HS driver slope value belongs in DT.
> > > >
> > > > Looks like it. Please hardcode the value for your platform in the driver
> > > > (with the comment), meanwhile we can try looking up the actual values.
> > >
> > > Do we have the values for a MTP/QRD (or whatever they used to be
> > > called
> > > back then..), like we would usually put in there?
> >
> > As far as I can understand msm-3.0 and msm-3.4 most of the boards were
> > writing 0 here (although it might have been unexpected). None of the
> > board files set the hsdrvslope value (which means 0).
> >
> > Please correct me if I'm wrong. I see that for tenderloin kernels change
> > that to 0x5, but I can't find a sensible commit message.
> >
> > I could not find the documentation for vendor ULPI registers for those
> > chips, so I don't think we can identify, how to make sense of those
> > values. In such a case and having different board-specific values, we
> > don't have a better option than having a qcom,hsdrvslope (or similarly
> > named) property in DT.
> Dmitry/Konrad,
>
> The bit-level meaning *is* documented byte-for-byte across
> every MSM8x60 downstream tree I could find: Code Aurora is the
> canonical source:
>
> arch/arm/mach-msm/include/mach/msm_hsusb_hw.h
>
> #define ULPI_CONFIG_REG3 0x32
> #define ULPI_DIGOUT_CTRL 0x36 /* on MSM7x30 / MSM8x60 */
> #define ULPI_CDR_AUTORESET (1 << 1)
> #define ULPI_SE1_GATE (1 << 2)
> #define ULPI_PRE_EMPHASIS_MASK (3 << 4)
> #define ULPI_HSDRVSLOPE_MASK (0x0F)
>
> reg 0x32 [5:4]: pre-emphasis level (00 disabled, 11 = 20%, 10 = 10%)
> reg 0x32 [3:0]: HS driver slope
> reg 0x36 bit 1: CDR auto-reset enable
> reg 0x36 bit 2: SE1 gating enable
>
> The legacy `msm72k_otg.c` semantics for the 0x36 bits are inverted:
> setting the bit disables the function (see set_cdr_auto_reset() and
> set_se1_gating()). Every MSM8x60 reference board sets both bits,
> i.e. CDR auto-reset disabled + SE1 gating disabled.
>
> Surveying every MSM8x60-class board file I can reach: Qualcomm's own
> reference, Samsung, Sony, HTC, and HP: the platform-level values
> are unanimous:
>
> pre-emphasis = 20%
> CDR auto-reset = disabled
> SE1 gating = disabled
>
> | Vendor / board | hsdrvslope |
> | -----------------------------------------------|------------|
> | Qualcomm reference (SURF / FFA / Fluid / | |
> | Dragon / Fusion -- board-msm8x60.c) | unset (0) |
> | Samsung Galaxy S2 family (Q1 / Celox / Dali / | |
> | generic 8x60 MTP) | unset (0) |
> | Sony MSM8660 (sony-kernel-msm8660) | unset (0) |
> | HTC MSM8660 (shooter / holiday / pyramid / | |
> | doubleshot / shooter_u / ruby) | 1 |
> | HP TouchPad (board-tenderloin.c) | 5 |
>
> So Qualcomm's own MTP, the closest thing to a reference platform we
> have, leaves hsdrvslope at the silicon default (0). Two OEMs (HTC,
> HP) override it to non-zero values that match their board layout.
> Neither override has a commit message. HTC's value is buried in an
> init_seq array, HP's appears as `.hsdrvslope = 0x05` in
> board-tenderloin.c with no comment. I've kept TouchPad's 5 because
> that's the value the device shipped with and our HS link is happy
> with it; changing it risks regressing eye margin on the silicon we
> still have to test against.
>
> So the plan is exactly what you both already converged on:
>
> 1. Drop qcom,vendor-init-seq from the binding (this patch goes away
> entirely).
> 2. In the driver, hardcode the three platform-level writes behind
> the qcom,usb-hs-phy-msm8660 compatible match-data, with a
> comment citing msm_hsusb_hw.h as the source for the bit names.
> 3. Add a single qcom,hs-drv-slope property (u8, 0..15) for the
> board-varying value. TouchPad DT sets 5. Absent ⇒ leave silicon
> default in place, matching Qualcomm/Samsung/Sony reference
> behaviour.
>
> I'll send the new v in that shape: single dt-bindings patch
> (qcom,hs-drv-slope) plus the driver patch that hardcodes the platform
> writes and consumes the new property.
Sounds good. Please explain in the commit messages that you can't decode
how the values correspond to the actual slope values (I couldn't find
corresponding doc inside Qualcomm).
--
With best wishes
Dmitry
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH V1 0/2] arm64: dts: qcom: Shikra SD Card support
From: Dmitry Baryshkov @ 2026-06-16 0:54 UTC (permalink / raw)
To: Monish Chunara
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vinod Koul, Neil Armstrong, Wesley Cheng,
Ulf Hansson, Kernel Team, linux-arm-msm, devicetree, linux-kernel,
linux-phy, linux-mmc, Nitin Rawat, Pradeep Pragallapati,
Komal Bajaj, Konrad Dybcio
In-Reply-To: <20260604122045.494712-1-monish.chunara@oss.qualcomm.com>
On Thu, Jun 04, 2026 at 05:50:43PM +0530, Monish Chunara wrote:
> This series adds SD card support for the Shikra platform.
>
> The first patch adds the SDHC2 controller node and the necessary pinctrl
> configurations to the base Shikra SoC dtsi. The second patch enables
> this support on the Shikra EVK (CQS, CQM, and IQS variants) by defining
> the regulator supplies and the card detection GPIO.
>
> Testing:
> - Validated on Shikra EVK variants.
>
> This series depends on:
> - https://lore.kernel.org/all/20260527-shikra-dt-v4-0-b5ca1fa0b392@oss.qualcomm.com/
> - https://lore.kernel.org/all/20260521-shikra-rproc-v3-0-2fca0bbe1ad7@oss.qualcomm.com/
> - https://lore.kernel.org/linux-devicetree/20260513-tsens_binding-v1-1-1780c6a6caf2@oss.qualcomm.com/
If the SD card depends on remote proc, tsens or cpufreq, then something
is wrong. Maybe, the way the serieas are organized and sent.
> - https://lore.kernel.org/all/20260524-shikra_epss_l3-v1-0-b1528a436134@oss.qualcomm.com/
> - https://lore.kernel.org/all/20260522-shikra-cpufreq-scaling-v4-0-f042a25896c5@oss.qualcomm.com/
> - https://lore.kernel.org/all/20260530-shikra-dt-m1-v2-0-6bb581035d13@oss.qualcomm.com/
>
> Monish Chunara (2):
> arm64: dts: qcom: Add SD Card support for Shikra SoC
> arm64: dts: qcom: Enable SD card for Shikra EVK
>
> arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts | 18 ++++
> arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts | 18 ++++
> arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts | 18 ++++
> arch/arm64/boot/dts/qcom/shikra.dtsi | 93 +++++++++++++++++++++
> 4 files changed, 147 insertions(+)
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: (subset) [PATCH v3 0/3] Add Hawi UFS PHY and Controller support
From: Martin K. Petersen @ 2026-06-16 2:26 UTC (permalink / raw)
To: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, mani, alim.akhtar,
bvanassche, andersson, dmitry.baryshkov, abel.vesa, luca.weiss,
palash.kambar
Cc: Martin K . Petersen, linux-arm-msm, linux-phy, devicetree,
linux-kernel, linux-scsi, nitin.rawat
In-Reply-To: <20260526090956.2340262-1-palash.kambar@oss.qualcomm.com>
On Tue, 26 May 2026 14:39:53 +0530, palash.kambar@oss.qualcomm.com wrote:
> 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.
>
> [...]
Applied to 7.2/scsi-queue, thanks!
[2/3] scsi: ufs: qcom: dt-bindings: Document the Hawi UFS controller
https://git.kernel.org/mkp/scsi/c/63977ab3c6a0
--
Martin K. Petersen
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v4 0/2] Enable the QMP PCIe PHY present in Qualcomm ipq5210 SoC
From: Varadarajan Narayanan @ 2026-06-16 5:04 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Varadarajan Narayanan, Dmitry Baryshkov
Document the bindings and update the driver to support
the PCIe phy present in Qualcomm ipq5210 SoC.
v4: Fix commit message for the bindings patch by removing redundant content
and adding explanation for using specific compatible.
v3: https://lore.kernel.org/linux-arm-msm/20260610-pcie-phy-v3-0-334011b378d6@oss.qualcomm.com/
Fix commit message for the bindings patch
Remove unused tables from the phy driver (ipq5210_gen3x1_pcie_ep_tx_tbl
and ipq5210_gen3x1_pcie_ep_pcs_tbl)
v2: https://lore.kernel.org/r/20260609-pcie-phy-v2-0-83bc80e79fa6@oss.qualcomm.com
Had incorrectly made both the phys as fallback. The single
lane phy is standalone and double lane uses ipq9574 as
fallback.
v1: https://lore.kernel.org/linux-arm-msm/20260514-pci-phy-v1-0-482429192746@oss.qualcomm.com/
Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
---
Varadarajan Narayanan (2):
dt-bindings: phy: qcom,ipq8074-qmp-pcie: Document the ipq5210 QMP PCIe PHY
phy: qcom-qmp-pcie: Add support for ipq5210 PCIe phys
.../bindings/phy/qcom,ipq8074-qmp-pcie-phy.yaml | 2 +
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 129 +++++++++++++++++++++
2 files changed, 131 insertions(+)
---
base-commit: a87737435cfa134f9cdcc696ba3080759d04cf72
change-id: 20260609-pcie-phy-99fcf91a02fd
prerequisite-change-id: 20260514-icc-ipq5210-0ab03f3a3e83:v1
prerequisite-patch-id: 0b6145b6635b18fe79fbbff5815041b43778c5ed
prerequisite-patch-id: 924c6ff7baf4283ac7991ee94c803a00fc5cece4
prerequisite-patch-id: c2fe1800fe769dccd37f94c19860a07f979e3c4c
Best regards,
--
Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v4 1/2] dt-bindings: phy: qcom,ipq8074-qmp-pcie: Document the ipq5210 QMP PCIe PHY
From: Varadarajan Narayanan @ 2026-06-16 5:04 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Varadarajan Narayanan
In-Reply-To: <20260616-pcie-phy-v4-0-504677c3d727@oss.qualcomm.com>
The ipq5210 has one dual lane and one single lane PCIe phy.
The dual lane phy is similar to the dual lane phy present in ipq9574. Hence
qcom,ipq5210-qmp-gen3x2-pcie-phy is documented with ipq9574's dual lane phy
as fallback compatible.
The single lane phy (qcom,ipq5210-qmp-gen3x1-pcie-phy) is documented as
specific compatible as it uses a combination of its own initialization
tables and some of the existing tables.
Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
---
Documentation/devicetree/bindings/phy/qcom,ipq8074-qmp-pcie-phy.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/qcom,ipq8074-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,ipq8074-qmp-pcie-phy.yaml
index f60804687412..fc155ad5fa6d 100644
--- a/Documentation/devicetree/bindings/phy/qcom,ipq8074-qmp-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,ipq8074-qmp-pcie-phy.yaml
@@ -17,6 +17,7 @@ properties:
compatible:
oneOf:
- enum:
+ - qcom,ipq5210-qmp-gen3x1-pcie-phy
- qcom,ipq6018-qmp-pcie-phy
- qcom,ipq8074-qmp-gen3-pcie-phy
- qcom,ipq8074-qmp-pcie-phy
@@ -28,6 +29,7 @@ properties:
- const: qcom,ipq9574-qmp-gen3x1-pcie-phy
- items:
- enum:
+ - qcom,ipq5210-qmp-gen3x2-pcie-phy
- qcom,ipq5424-qmp-gen3x2-pcie-phy
- const: qcom,ipq9574-qmp-gen3x2-pcie-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 v4 2/2] phy: qcom-qmp-pcie: Add support for ipq5210 PCIe phys
From: Varadarajan Narayanan @ 2026-06-16 5:04 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel,
Varadarajan Narayanan, Dmitry Baryshkov
In-Reply-To: <20260616-pcie-phy-v4-0-504677c3d727@oss.qualcomm.com>
Add support for a PCIe phys found on Qualcomm ipq5210 platform.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Varadarajan Narayanan <varadarajan.narayanan@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 129 +++++++++++++++++++++++++++++++
1 file changed, 129 insertions(+)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index d3effad7a074..1762ccadc793 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -620,6 +620,89 @@ static const struct qmp_phy_init_tbl ipq8074_pcie_gen3_pcs_misc_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
};
+static const struct qmp_phy_init_tbl ipq5210_gen3x1_pcie_ep_serdes_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TIMER, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CLKBUFLR_EN, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_BUF_ENABLE, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_IVCO, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE0, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE0, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE1, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE1, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TRIM, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE0, 0x23),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE1, 0x23),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE0, 0x10),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE1, 0x10),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE0, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE1, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CTRL_BY_PSM, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_EN_SEL, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_RESETSM_CNTRL, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP_EN, 0x42),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE0, 0x19),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE1, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE0, 0xfe),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN1_MODE0, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE1, 0xfe),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN1_MODE1, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE0, 0x24),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE0, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE1, 0xb4),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE1, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CMN_CONFIG, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV_MODE1, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SYS_CLK_CTRL, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_EN_SEL, 0x10),
+};
+
+static const struct qmp_phy_init_tbl ipq5210_gen3x1_pcie_ep_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x70),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x61),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1e),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x73),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_ENABLES, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xf0),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x2f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0xd3),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x40),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
+};
+
+static const struct qmp_phy_init_tbl ipq5210_gen3x1_pcie_ep_pcs_misc_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG2, 0x04),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG1, 0x11),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_PRE, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_POST, 0x58),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_CONFIG1, 0x02),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_CONFIG4, 0xff),
+};
+
static const struct qmp_phy_init_tbl ipq9574_gen3x1_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CLKBUFLR_EN, 0x18),
QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CTRL_BY_PSM, 0x01),
@@ -3746,6 +3829,49 @@ static const struct qmp_phy_cfg ipq6018_pciephy_cfg = {
.phy_status = PHYSTATUS,
};
+static const struct qmp_phy_cfg ipq5210_gen3x1_pciephy_cfg = {
+ .lanes = 1,
+
+ .offsets = &qmp_pcie_offsets_v4x1,
+
+ .tbls = {
+ .serdes = ipq9574_gen3x1_pcie_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(ipq9574_gen3x1_pcie_serdes_tbl),
+ .tx = ipq8074_pcie_gen3_tx_tbl,
+ .tx_num = ARRAY_SIZE(ipq8074_pcie_gen3_tx_tbl),
+ .rx = ipq9574_pcie_rx_tbl,
+ .rx_num = ARRAY_SIZE(ipq9574_pcie_rx_tbl),
+ .pcs = ipq9574_gen3x1_pcie_pcs_tbl,
+ .pcs_num = ARRAY_SIZE(ipq9574_gen3x1_pcie_pcs_tbl),
+ .pcs_misc = ipq9574_gen3x1_pcie_pcs_misc_tbl,
+ .pcs_misc_num = ARRAY_SIZE(ipq9574_gen3x1_pcie_pcs_misc_tbl),
+ },
+
+ .tbls_ep = &(const struct qmp_phy_cfg_tbls) {
+ .serdes = ipq5210_gen3x1_pcie_ep_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(ipq5210_gen3x1_pcie_ep_serdes_tbl),
+ .tx = ipq6018_pcie_tx_tbl,
+ .tx_num = ARRAY_SIZE(ipq6018_pcie_tx_tbl),
+ .rx = ipq5210_gen3x1_pcie_ep_rx_tbl,
+ .rx_num = ARRAY_SIZE(ipq5210_gen3x1_pcie_ep_rx_tbl),
+ .pcs = ipq6018_pcie_pcs_tbl,
+ .pcs_num = ARRAY_SIZE(ipq6018_pcie_pcs_tbl),
+ .pcs_misc = ipq5210_gen3x1_pcie_ep_pcs_misc_tbl,
+ .pcs_misc_num = ARRAY_SIZE(ipq5210_gen3x1_pcie_ep_pcs_misc_tbl),
+ },
+
+ .reset_list = ipq8074_pciephy_reset_l,
+ .num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
+ .vreg_list = NULL,
+ .num_vregs = 0,
+ .regs = pciephy_v4_regs_layout,
+
+ .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
+ .phy_status = PHYSTATUS,
+
+ .pipe_clock_rate = 250000000,
+};
+
static const struct qmp_phy_cfg ipq9574_gen3x1_pciephy_cfg = {
.lanes = 1,
@@ -5543,6 +5669,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
}, {
.compatible = "qcom,glymur-qmp-gen5x4-pcie-phy",
.data = &glymur_qmp_gen5x4_pciephy_cfg,
+ }, {
+ .compatible = "qcom,ipq5210-qmp-gen3x1-pcie-phy",
+ .data = &ipq5210_gen3x1_pciephy_cfg,
}, {
.compatible = "qcom,ipq6018-qmp-pcie-phy",
.data = &ipq6018_pciephy_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
* Re: [PATCH v3 2/4] dt-bindings: phy: qcom,qcs615-qmp-usb3-dp-phy: Add support for Shikra
From: Krzysztof Kozlowski @ 2026-06-16 5:07 UTC (permalink / raw)
To: Krishna Kurapati, 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
In-Reply-To: <9569b594-a4b8-4e67-ac61-5eb2914bfc76@oss.qualcomm.com>
On 15/06/2026 21:02, Krishna Kurapati wrote:
>>> 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.
>>
> The resets needed on Shikra are:
>
> GCC_USB3PHY_PHY_PRIM_SP0_BCR
> GCC_USB3_DP_PHY_PRIM_BCR
> GCC_USB3_PHY_PRIM_SP0_BCR
>
> Hence named the third one as "phy".
Maybe dataheet of this device has more meaningful names? The names here
do not come from the GCC (the reset provider) but from consumer pins.
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 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled VBUS regulator
From: Claudiu Beznea @ 2026-06-16 8:28 UTC (permalink / raw)
To: Biju Das, biju.das.au, Yoshihiro Shimoda, Vinod Koul,
Geert Uytterhoeven, magnus.damm
Cc: Neil Armstrong, Philipp Zabel, linux-renesas-soc@vger.kernel.org,
linux-phy@lists.infradead.org, linux-kernel@vger.kernel.org,
Prabhakar Mahadev Lad, stable, Greg Kroah-Hartman
In-Reply-To: <TY3PR01MB113460C85EEF713331411FBEC86E62@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Hi, Biju,
On 6/15/26 15:42, Biju Das wrote:
> Hi Claudiu,
>
> + stable <stable@kernel.org>
>
>> -----Original Message-----
>> From: Claudiu Beznea <claudiu.beznea@tuxon.dev>
>> Sent: 15 June 2026 10:37
>> Subject: Re: [PATCH 09/11] phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled
>> VBUS regulator
>>
>> Hi, Biju,
>>
>> On 6/12/26 17:30, Biju wrote:
>>> From: Biju Das <biju.das.jz@bp.renesas.com>
>>>
>>> devm_regulator_get_exclusive() initialises the regulator with
>>> enable_count = 1, requiring the consumer to disable it before release.
>>>
>>> Previously, the devm disable action was only registered when the
>>> regulator was explicitly enabled, causing the cleanup path to skip
>>> decrementing enable_count on device removal when the regulator was
>>> left disabled.
>>>
>>> Fix this by always registering the devm disable action when the
>>> regulator is enabled (checked via regulator_is_enabled()), covering
>>> both the explicitly-enabled case and the initial state set by
>>> devm_regulator_get_exclusive().
>>>
>>> This fixes WARN_ON enable count during regulator release.
>>>
>>> Fixes: 24843404efe4 ("phy: renesas: phy-rcar-gen3-usb2: Control VBUS
>>> for RZ/G2L SoCs")
>>> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
>>
>> The approach in this patch don't solve the problem, at least on RZ/G3S. See [1] for logs.
>>
>> I applied this patch on next-20260610:
>>
>> git log --oneline -2
>> afe09f11d549 (HEAD) phy: renesas: phy-rcar-gen3-usb2: Fix devm action registration for disabled VBUS
>> regulator
>> abe651837cb3 (tag: next-20260610, linux-next/master) Add linux-next specific files for 20260610
>>
>> [1]
>> https://github.com/claudiubeznea/logs/blob/2f1bab20407dfe6031385819ffeabfc4eac772bd/logs
>
> This issue is introduced by the commit
>
> eb9ac779830b223584 ("usb: renesas_usbhs: Fix synchronous external abort on unbind")
Indeed, nice catch. I reverted this commit (just for checking the patch you
proposed) and and now it looks good on RZ/G2L. Code from commit eb9ac779830b
("usb: renesas_usbhs: Fix synchronous external abort on unbind") will have to be
adjusted.
Thank you for investigation,
Claudiu
--
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