From 0696cc735dc7ff53297ad2ee649ceed3b1f93d07 Mon Sep 17 00:00:00 2001 From: Matthew Leung Date: Tue, 7 Jul 2026 20:32:47 +0000 Subject: phy: qcom-qmp: Add v10 register offsets Hawi SoC uses v10 register definitions for PCIe Gen3 x2. Add the new register offset headers for all four sub-blocks: - QSERDES-COM offsets - QSERDES TX/RX offsets - PCS offsets - PCS PCIe-specific offsets Signed-off-by: Matthew Leung Reviewed-by: Dmitry Baryshkov Link: https://patch.msgid.link/20260707-hawi-phy-pcie-v4-2-8d9cc6324947@oss.qualcomm.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 1 + drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v10.h | 18 ++++++++ drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10.h | 22 ++++++++++ .../phy/qualcomm/phy-qcom-qmp-qserdes-com-v10.h | 49 ++++++++++++++++++++++ .../phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v10.h | 47 +++++++++++++++++++++ drivers/phy/qualcomm/phy-qcom-qmp.h | 5 +++ 6 files changed, 142 insertions(+) create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v10.h create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10.h create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v10.h create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v10.h (limited to 'drivers') diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c index d3effad7a074..5a26347d0fc9 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c @@ -40,6 +40,7 @@ #include "phy-qcom-qmp-qserdes-com-v8.h" #include "phy-qcom-qmp-pcs-pcie-v8.h" #include "phy-qcom-qmp-qserdes-txrx-pcie-v8.h" +#include "phy-qcom-qmp-pcs-pcie-v10.h" #define PHY_INIT_COMPLETE_TIMEOUT 10000 diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v10.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v10.h new file mode 100644 index 000000000000..2cdcc211bd93 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v10.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef QCOM_PHY_QMP_PCS_PCIE_V10_H_ +#define QCOM_PHY_QMP_PCS_PCIE_V10_H_ + +/* Only for QMP V10 PHY - PCIE PCS registers */ +#define QPHY_PCIE_V10_PCS_POWER_STATE_CONFIG2 0x00c +#define QPHY_PCIE_V10_PCS_POWER_STATE_CONFIG4 0x014 +#define QPHY_PCIE_V10_PCS_ENDPOINT_REFCLK_DRIVE 0x020 +#define QPHY_PCIE_V10_PCS_OSC_DTCT_ACTIONS 0x094 +#define QPHY_PCIE_V10_PCS_EQ_CONFIG1 0x0a4 +#define QPHY_PCIE_V10_PCS_RXEQEVAL_TIME 0x0f4 +#define QPHY_PCIE_V10_PCS_POWER_STATE_CONFIG6 0x0f8 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10.h new file mode 100644 index 000000000000..165ce8a28f61 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef QCOM_PHY_QMP_PCS_V10_H_ +#define QCOM_PHY_QMP_PCS_V10_H_ + +/* Only for QMP V10 PHY - PCIe PCS registers */ +#define QPHY_V10_PCS_SW_RESET 0x000 +#define QPHY_V10_PCS_PCS_STATUS1 0x014 +#define QPHY_V10_PCS_POWER_DOWN_CONTROL 0x040 +#define QPHY_V10_PCS_START_CONTROL 0x044 +#define QPHY_V10_PCS_REFGEN_REQ_CONFIG1 0x0dc +#define QPHY_V10_PCS_G12S1_TXDEEMPH_M6DB 0x168 +#define QPHY_V10_PCS_G3S2_PRE_GAIN 0x170 +#define QPHY_V10_PCS_RX_SIGDET_LVL 0x188 +#define QPHY_V10_PCS_RATE_SLEW_CNTRL1 0x198 +#define QPHY_V10_PCS_PCS_TX_RX_CONFIG 0x1d0 +#define QPHY_V10_PCS_EQ_CONFIG2 0x1e4 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v10.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v10.h new file mode 100644 index 000000000000..09199e7b4aac --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v10.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef QCOM_PHY_QMP_QSERDES_COM_V10_H_ +#define QCOM_PHY_QMP_QSERDES_COM_V10_H_ + +/* Only for QMP V10 PHY - QSERDES COM registers */ +#define QSERDES_V10_COM_SSC_STEP_SIZE1_MODE1 0x00 +#define QSERDES_V10_COM_SSC_STEP_SIZE2_MODE1 0x04 +#define QSERDES_V10_COM_CP_CTRL_MODE1 0x10 +#define QSERDES_V10_COM_PLL_RCTRL_MODE1 0x14 +#define QSERDES_V10_COM_PLL_CCTRL_MODE1 0x18 +#define QSERDES_V10_COM_CORECLK_DIV_MODE1 0x1c +#define QSERDES_V10_COM_LOCK_CMP1_MODE1 0x20 +#define QSERDES_V10_COM_LOCK_CMP2_MODE1 0x24 +#define QSERDES_V10_COM_DEC_START_MODE1 0x28 +#define QSERDES_V10_COM_DIV_FRAC_START1_MODE1 0x30 +#define QSERDES_V10_COM_DIV_FRAC_START2_MODE1 0x34 +#define QSERDES_V10_COM_DIV_FRAC_START3_MODE1 0x38 +#define QSERDES_V10_COM_HSCLK_SEL_1 0x3c +#define QSERDES_V10_COM_SSC_STEP_SIZE1_MODE0 0x60 +#define QSERDES_V10_COM_SSC_STEP_SIZE2_MODE0 0x64 +#define QSERDES_V10_COM_CP_CTRL_MODE0 0x70 +#define QSERDES_V10_COM_PLL_RCTRL_MODE0 0x74 +#define QSERDES_V10_COM_PLL_CCTRL_MODE0 0x78 +#define QSERDES_V10_COM_LOCK_CMP1_MODE0 0x80 +#define QSERDES_V10_COM_LOCK_CMP2_MODE0 0x84 +#define QSERDES_V10_COM_DEC_START_MODE0 0x88 +#define QSERDES_V10_COM_DIV_FRAC_START1_MODE0 0x90 +#define QSERDES_V10_COM_DIV_FRAC_START2_MODE0 0x94 +#define QSERDES_V10_COM_DIV_FRAC_START3_MODE0 0x98 +#define QSERDES_V10_COM_BG_TIMER 0xbc +#define QSERDES_V10_COM_SSC_EN_CENTER 0xc0 +#define QSERDES_V10_COM_SSC_PER1 0xcc +#define QSERDES_V10_COM_SSC_PER2 0xd0 +#define QSERDES_V10_COM_CLK_ENABLE1 0xe0 +#define QSERDES_V10_COM_SYS_CLK_CTRL 0xe4 +#define QSERDES_V10_COM_PLL_IVCO 0xf4 +#define QSERDES_V10_COM_SYSCLK_EN_SEL 0x110 +#define QSERDES_V10_COM_LOCK_CMP_EN 0x120 +#define QSERDES_V10_COM_VCO_TUNE_MAP 0x140 +#define QSERDES_V10_COM_CLK_SELECT 0x164 +#define QSERDES_V10_COM_CORE_CLK_EN 0x170 +#define QSERDES_V10_COM_CMN_CONFIG_1 0x174 +#define QSERDES_V10_COM_ADDITIONAL_MISC_3 0x1bc + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v10.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v10.h new file mode 100644 index 000000000000..d81ebdde0063 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v10.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef QCOM_PHY_QMP_QSERDES_TXRX_V10_H_ +#define QCOM_PHY_QMP_QSERDES_TXRX_V10_H_ + +#define QSERDES_V10_TX_RES_CODE_LANE_OFFSET_TX 0x03c +#define QSERDES_V10_TX_RES_CODE_LANE_OFFSET_RX 0x040 +#define QSERDES_V10_TX_LANE_MODE_1 0x084 +#define QSERDES_V10_TX_LANE_MODE_3 0x08c +#define QSERDES_V10_TX_LANE_MODE_4 0x090 +#define QSERDES_V10_TX_LANE_MODE_5 0x094 +#define QSERDES_V10_TX_PI_QEC_CTRL 0x0e4 + +#define QSERDES_V10_RX_UCDR_FO_GAIN 0x008 +#define QSERDES_V10_RX_UCDR_SO_GAIN 0x014 +#define QSERDES_V10_RX_UCDR_SB2_THRESH1 0x04c +#define QSERDES_V10_RX_UCDR_SB2_THRESH2 0x050 +#define QSERDES_V10_RX_TX_ADAPT_PRE_THRESH1 0x0c4 +#define QSERDES_V10_RX_TX_ADAPT_PRE_THRESH2 0x0c8 +#define QSERDES_V10_RX_TX_ADAPT_POST_THRESH 0x0cc +#define QSERDES_V10_RX_VGA_CAL_CNTRL2 0x0d8 +#define QSERDES_V10_RX_GM_CAL 0x0dc +#define QSERDES_V10_RX_RX_IDAC_TSETTLE_LOW 0x0f8 +#define QSERDES_V10_RX_SIGDET_ENABLES 0x118 +#define QSERDES_V10_RX_SIGDET_CNTRL 0x11c +#define QSERDES_V10_RX_RX_MODE_00_LOW 0x15c +#define QSERDES_V10_RX_RX_MODE_00_HIGH 0x160 +#define QSERDES_V10_RX_RX_MODE_00_HIGH2 0x164 +#define QSERDES_V10_RX_RX_MODE_00_HIGH3 0x168 +#define QSERDES_V10_RX_RX_MODE_00_HIGH4 0x16c +#define QSERDES_V10_RX_RX_MODE_01_LOW 0x170 +#define QSERDES_V10_RX_RX_MODE_01_HIGH 0x174 +#define QSERDES_V10_RX_RX_MODE_01_HIGH2 0x178 +#define QSERDES_V10_RX_RX_MODE_01_HIGH3 0x17c +#define QSERDES_V10_RX_RX_MODE_01_HIGH4 0x180 +#define QSERDES_V10_RX_RX_MODE_10_LOW 0x184 +#define QSERDES_V10_RX_RX_MODE_10_HIGH 0x188 +#define QSERDES_V10_RX_RX_MODE_10_HIGH2 0x18c +#define QSERDES_V10_RX_RX_MODE_10_HIGH3 0x190 +#define QSERDES_V10_RX_RX_MODE_10_HIGH4 0x194 +#define QSERDES_V10_RX_DFE_CTLE_POST_CAL_OFFSET 0x1a4 +#define QSERDES_V10_RX_SIGDET_CAL_TRIM 0x1f8 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h index 11b7e03b4fab..e4237e374404 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp.h @@ -36,6 +36,9 @@ #include "phy-qcom-qmp-qserdes-txrx-v8.h" #include "phy-qcom-qmp-qserdes-lalb-v8.h" +#include "phy-qcom-qmp-qserdes-com-v10.h" +#include "phy-qcom-qmp-qserdes-txrx-v10.h" + #include "phy-qcom-qmp-qserdes-pll.h" #include "phy-qcom-qmp-pcs-v2.h" @@ -62,6 +65,8 @@ #include "phy-qcom-qmp-pcs-v8_50.h" +#include "phy-qcom-qmp-pcs-v10.h" + /* QPHY_SW_RESET bit */ #define SW_RESET BIT(0) /* QPHY_POWER_DOWN_CONTROL */ -- cgit v1.2.3 From fdfe6417e2e699890f51bcc0b772734a0431e5d2 Mon Sep 17 00:00:00 2001 From: Matthew Leung Date: Tue, 7 Jul 2026 20:32:48 +0000 Subject: phy: qcom-qmp: Add v10.60 register offsets Hawi SoC uses v10.60 register definitions for PCIe Gen4 x1. Add the new register offset headers for all four sub-blocks: - QSERDES-COM offsets - QSERDES TX/RX offsets - PCS offsets - PCS PCIe-specific offsets Signed-off-by: Matthew Leung Reviewed-by: Dmitry Baryshkov Link: https://patch.msgid.link/20260707-hawi-phy-pcie-v4-3-8d9cc6324947@oss.qualcomm.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 1 + .../phy/qualcomm/phy-qcom-qmp-pcs-pcie-v10_60.h | 26 +++++ drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10_60.h | 23 +++++ .../phy/qualcomm/phy-qcom-qmp-qserdes-com-v10_60.h | 55 +++++++++++ .../qualcomm/phy-qcom-qmp-qserdes-txrx-v10_60.h | 109 +++++++++++++++++++++ drivers/phy/qualcomm/phy-qcom-qmp.h | 5 + 6 files changed, 219 insertions(+) create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v10_60.h create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10_60.h create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v10_60.h create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v10_60.h (limited to 'drivers') diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c index 5a26347d0fc9..9f933eff3f12 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c @@ -41,6 +41,7 @@ #include "phy-qcom-qmp-pcs-pcie-v8.h" #include "phy-qcom-qmp-qserdes-txrx-pcie-v8.h" #include "phy-qcom-qmp-pcs-pcie-v10.h" +#include "phy-qcom-qmp-pcs-pcie-v10_60.h" #define PHY_INIT_COMPLETE_TIMEOUT 10000 diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v10_60.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v10_60.h new file mode 100644 index 000000000000..2df5a45010a4 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v10_60.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef QCOM_PHY_QMP_PCS_PCIE_V10_60_H_ +#define QCOM_PHY_QMP_PCS_PCIE_V10_60_H_ + +/* Only for QMP V10_60 PHY - PCIE PCS registers */ +#define QPHY_PCIE_V10_60_PCS_POWER_STATE_CONFIG2 0x00c +#define QPHY_PCIE_V10_60_PCS_TX_RX_CONFIG 0x018 +#define QPHY_PCIE_V10_60_PCS_ENDPOINT_REFCLK_DRIVE 0x01c +#define QPHY_PCIE_V10_60_PCS_OSC_DTCT_ACTIONS 0x090 +#define QPHY_PCIE_V10_60_PCS_EQ_CONFIG1 0x0a0 +#define QPHY_PCIE_V10_60_PCS_G3_RXEQEVAL_TIME 0x0f0 +#define QPHY_PCIE_V10_60_PCS_G4_RXEQEVAL_TIME 0x0f4 +#define QPHY_PCIE_V10_60_PCS_G4_EQ_CONFIG5 0x108 +#define QPHY_PCIE_V10_60_PCS_G4_PRE_GAIN 0x15c +#define QPHY_PCIE_V10_60_PCS_RX_MARGINING_CONFIG1 0x17c +#define QPHY_PCIE_V10_60_PCS_RX_MARGINING_CONFIG3 0x184 +#define QPHY_PCIE_V10_60_PCS_RX_MARGINING_CONFIG5 0x18c +#define QPHY_PCIE_V10_60_PCS_G3_FOM_EQ_CONFIG5 0x1ac +#define QPHY_PCIE_V10_60_PCS_G4_FOM_EQ_CONFIG5 0x1c0 +#define QPHY_PCIE_V10_60_PCS_POWER_STATE_CONFIG6 0x1d0 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10_60.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10_60.h new file mode 100644 index 000000000000..e4558b69489d --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v10_60.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef QCOM_PHY_QMP_PCS_V10_60_H_ +#define QCOM_PHY_QMP_PCS_V10_60_H_ + +/* Only for QMP V10_60 PHY - PCIe PCS registers */ +#define QPHY_V10_60_PCS_SW_RESET 0x000 +#define QPHY_V10_60_PCS_PCS_STATUS1 0x014 +#define QPHY_V10_60_PCS_POWER_DOWN_CONTROL 0x040 +#define QPHY_V10_60_PCS_START_CONTROL 0x044 +#define QPHY_V10_60_PCS_G12S1_TXDEEMPH_M6DB 0x170 +#define QPHY_V10_60_PCS_G3S2_PRE_GAIN 0x178 +#define QPHY_V10_60_PCS_RX_SIGDET_LVL 0x190 +#define QPHY_V10_60_PCS_ELECIDLE_DLY_SEL 0x1b8 +#define QPHY_V10_60_PCS_PCS_TX_RX_CONFIG1 0x1dc +#define QPHY_V10_60_PCS_PCS_TX_RX_CONFIG2 0x1e0 +#define QPHY_V10_60_PCS_EQ_CONFIG4 0x1f8 +#define QPHY_V10_60_PCS_EQ_CONFIG5 0x1fc + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v10_60.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v10_60.h new file mode 100644 index 000000000000..39351bef8b63 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v10_60.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef QCOM_PHY_QMP_QSERDES_COM_V10_60_H_ +#define QCOM_PHY_QMP_QSERDES_COM_V10_60_H_ + +/* Only for QMP V10_60 PHY - QSERDES COM registers */ +#define QSERDES_V10_60_COM_SSC_STEP_SIZE1_MODE1 0x00 +#define QSERDES_V10_60_COM_SSC_STEP_SIZE2_MODE1 0x04 +#define QSERDES_V10_60_COM_CP_CTRL_MODE1 0x10 +#define QSERDES_V10_60_COM_PLL_RCTRL_MODE1 0x14 +#define QSERDES_V10_60_COM_PLL_CCTRL_MODE1 0x18 +#define QSERDES_V10_60_COM_CORECLK_DIV_MODE1 0x1c +#define QSERDES_V10_60_COM_LOCK_CMP1_MODE1 0x20 +#define QSERDES_V10_60_COM_LOCK_CMP2_MODE1 0x24 +#define QSERDES_V10_60_COM_DEC_START_MODE1 0x28 +#define QSERDES_V10_60_COM_DIV_FRAC_START1_MODE1 0x30 +#define QSERDES_V10_60_COM_DIV_FRAC_START2_MODE1 0x34 +#define QSERDES_V10_60_COM_DIV_FRAC_START3_MODE1 0x38 +#define QSERDES_V10_60_COM_HSCLK_SEL_1 0x3c +#define QSERDES_V10_60_COM_SSC_STEP_SIZE1_MODE0 0x60 +#define QSERDES_V10_60_COM_SSC_STEP_SIZE2_MODE0 0x64 +#define QSERDES_V10_60_COM_CP_CTRL_MODE0 0x70 +#define QSERDES_V10_60_COM_PLL_RCTRL_MODE0 0x74 +#define QSERDES_V10_60_COM_PLL_CCTRL_MODE0 0x78 +#define QSERDES_V10_60_COM_CORECLK_DIV_MODE0 0x7c +#define QSERDES_V10_60_COM_LOCK_CMP1_MODE0 0x80 +#define QSERDES_V10_60_COM_LOCK_CMP2_MODE0 0x84 +#define QSERDES_V10_60_COM_DEC_START_MODE0 0x88 +#define QSERDES_V10_60_COM_DIV_FRAC_START1_MODE0 0x90 +#define QSERDES_V10_60_COM_DIV_FRAC_START2_MODE0 0x94 +#define QSERDES_V10_60_COM_DIV_FRAC_START3_MODE0 0x98 +#define QSERDES_V10_60_COM_HSCLK_HS_SWITCH_SEL_1 0x9c +#define QSERDES_V10_60_COM_BG_TIMER 0xbc +#define QSERDES_V10_60_COM_SSC_PER1 0xcc +#define QSERDES_V10_60_COM_SSC_PER2 0xd0 +#define QSERDES_V10_60_COM_BIAS_EN_CLKBUFLR_EN 0xdc +#define QSERDES_V10_60_COM_CLK_ENABLE1 0xe0 +#define QSERDES_V10_60_COM_SYS_CLK_CTRL 0xe4 +#define QSERDES_V10_60_COM_PLL_IVCO 0xf4 +#define QSERDES_V10_60_COM_SYSCLK_EN_SEL 0x110 +#define QSERDES_V10_60_COM_LOCK_CMP_EN 0x120 +#define QSERDES_V10_60_COM_LOCK_CMP_CFG 0x124 +#define QSERDES_V10_60_COM_VCO_TUNE_MAP 0x140 +#define QSERDES_V10_60_COM_CLK_SELECT 0x164 +#define QSERDES_V10_60_COM_CORE_CLK_EN 0x170 +#define QSERDES_V10_60_COM_CMN_CONFIG_1 0x174 +#define QSERDES_V10_60_COM_CMN_MISC1 0x184 +#define QSERDES_V10_60_COM_CMN_MODE 0x188 +#define QSERDES_V10_60_COM_VCO_DC_LEVEL_CTRL 0x198 +#define QSERDES_V10_60_COM_PLL_SPARE_FOR_ECO 0x2b4 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v10_60.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v10_60.h new file mode 100644 index 000000000000..3150a494685e --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v10_60.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef QCOM_PHY_QMP_QSERDES_TXRX_V10_60_H_ +#define QCOM_PHY_QMP_QSERDES_TXRX_V10_60_H_ + +#define QSERDES_V10_60_TXRX_RES_CODE_LANE_OFFSET_TX 0x034 +#define QSERDES_V10_60_TXRX_RES_CODE_LANE_OFFSET_RX 0x038 +#define QSERDES_V10_60_TXRX_LANE_MODE_1 0x080 +#define QSERDES_V10_60_TXRX_LANE_MODE_2 0x084 +#define QSERDES_V10_60_TXRX_LANE_MODE_3 0x088 +#define QSERDES_V10_60_TXRX_UCDR_FASTLOCK_FO_GAIN_RATE1 0x0c8 +#define QSERDES_V10_60_TXRX_UCDR_FASTLOCK_FO_GAIN_RATE2 0x0cc +#define QSERDES_V10_60_TXRX_UCDR_FASTLOCK_FO_GAIN_RATE3 0x0d0 +#define QSERDES_V10_60_TXRX_UCDR_FASTLOCK_FO_GAIN_RATE4 0x0d4 +#define QSERDES_V10_60_TXRX_UCDR_FASTLOCK_SO_GAIN_RATE1 0x0e0 +#define QSERDES_V10_60_TXRX_UCDR_FASTLOCK_SO_GAIN_RATE2 0x0e4 +#define QSERDES_V10_60_TXRX_UCDR_FASTLOCK_SO_GAIN_RATE3 0x0e8 +#define QSERDES_V10_60_TXRX_UCDR_FASTLOCK_SO_GAIN_RATE4 0x0ec +#define QSERDES_V10_60_TXRX_UCDR_PI_CTRL1 0x12c +#define QSERDES_V10_60_TXRX_UCDR_PI_CTRL2 0x130 +#define QSERDES_V10_60_TXRX_UCDR_PI_CTRL3 0x134 +#define QSERDES_V10_60_TXRX_UCDR_PI_CTRL4 0x138 +#define QSERDES_V10_60_TXRX_SVS_MODE_CTRL 0x19c +#define QSERDES_V10_60_TXRX_RXCLK_DIV2_CTRL 0x1a0 +#define QSERDES_V10_60_TXRX_RX_BAND_CTRL0 0x1a4 +#define QSERDES_V10_60_TXRX_RX_TERM_BW_CTRL0 0x1ac +#define QSERDES_V10_60_TXRX_RX_TERM_BW_CTRL1 0x1b0 +#define QSERDES_V10_60_TXRX_UCDR_FO_GAIN_RATE1 0x1b8 +#define QSERDES_V10_60_TXRX_UCDR_FO_GAIN_RATE2 0x1bc +#define QSERDES_V10_60_TXRX_UCDR_FO_GAIN_RATE3 0x1c0 +#define QSERDES_V10_60_TXRX_UCDR_FO_GAIN_RATE4 0x1c4 +#define QSERDES_V10_60_TXRX_UCDR_SO_GAIN_RATE1 0x1d0 +#define QSERDES_V10_60_TXRX_UCDR_SO_GAIN_RATE2 0x1d4 +#define QSERDES_V10_60_TXRX_UCDR_SO_GAIN_RATE3 0x1d8 +#define QSERDES_V10_60_TXRX_UCDR_SO_GAIN_RATE4 0x1dc +#define QSERDES_V10_60_TXRX_UCDR_PI_CONTROLS 0x1e4 +#define QSERDES_V10_60_TXRX_AUXDATA_BIN_RATE3 0x200 +#define QSERDES_V10_60_TXRX_AUXDATA_BIN_RATE4 0x204 +#define QSERDES_V10_60_TXRX_EOM_MAX_ERR_LIMIT_LSB 0x218 +#define QSERDES_V10_60_TXRX_EOM_MAX_ERR_LIMIT_MSB 0x21c +#define QSERDES_V10_60_TXRX_VGA_CAL_CNTRL1 0x280 +#define QSERDES_V10_60_TXRX_VGA_CAL_MAN_VAL 0x288 +#define QSERDES_V10_60_TXRX_GM_CAL 0x29c +#define QSERDES_V10_60_TXRX_RX_EQU_ADAPTOR_CNTRL6 0x2b8 +#define QSERDES_V10_60_TXRX_SIGDET_ENABLES 0x2d4 +#define QSERDES_V10_60_TXRX_SIGDET_CNTRL 0x2d8 +#define QSERDES_V10_60_TXRX_SIGDET_LVL 0x2dc +#define QSERDES_V10_60_TXRX_SIGDET_DEGLITCH_CNTRL 0x2e0 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B0 0x314 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B1 0x318 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B2 0x31c +#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B3 0x320 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B4 0x324 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B5 0x328 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B6 0x32c +#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B7 0x330 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B8 0x334 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B9 0x338 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B10 0x33c +#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B0 0x340 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B1 0x344 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B2 0x348 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B3 0x34c +#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B4 0x350 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B5 0x354 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B6 0x358 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B7 0x35c +#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B8 0x360 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B9 0x364 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE2_B10 0x368 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B0 0x36c +#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B1 0x370 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B2 0x374 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B3 0x378 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B4 0x37c +#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B5 0x380 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B6 0x384 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B7 0x388 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B8 0x38c +#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B9 0x390 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE3_B10 0x394 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B0 0x398 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B1 0x39c +#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B2 0x3a0 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B3 0x3a4 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B4 0x3a8 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B5 0x3ac +#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B6 0x3b0 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B7 0x3b4 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B8 0x3b8 +#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B9 0x3bc +#define QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B10 0x3c0 +#define QSERDES_V10_60_TXRX_Q_PI_INTRINSIC_BIAS_RATE32 0x478 +#define QSERDES_V10_60_TXRX_Q_PI_INTRINSIC_BIAS_RATE45 0x47c +#define QSERDES_V10_60_TXRX_SIGDET_CAL_CTRL1 0x4c8 +#define QSERDES_V10_60_TXRX_SIGDET_CAL_CTRL2 0x4cc +#define QSERDES_V10_60_TXRX_SIGDET_CAL_TRIM 0x4d0 +#define QSERDES_V10_60_TXRX_TX_BAND0 0x4e8 +#define QSERDES_V10_60_TXRX_TX_BAND1 0x4ec +#define QSERDES_V10_60_TXRX_SEL_10B_8B 0x4f4 +#define QSERDES_V10_60_TXRX_SEL_20B_10B 0x4f8 +#define QSERDES_V10_60_TXRX_EQ_RCF_CTRL_RATE3 0x53c +#define QSERDES_V10_60_TXRX_EQ_RCF_CTRL_RATE4 0x540 +#define QSERDES_V10_60_TXRX_PHPRE_CTRL 0x5e8 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h index e4237e374404..10eb97aa8706 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp.h @@ -39,6 +39,9 @@ #include "phy-qcom-qmp-qserdes-com-v10.h" #include "phy-qcom-qmp-qserdes-txrx-v10.h" +#include "phy-qcom-qmp-qserdes-com-v10_60.h" +#include "phy-qcom-qmp-qserdes-txrx-v10_60.h" + #include "phy-qcom-qmp-qserdes-pll.h" #include "phy-qcom-qmp-pcs-v2.h" @@ -67,6 +70,8 @@ #include "phy-qcom-qmp-pcs-v10.h" +#include "phy-qcom-qmp-pcs-v10_60.h" + /* QPHY_SW_RESET bit */ #define SW_RESET BIT(0) /* QPHY_POWER_DOWN_CONTROL */ -- cgit v1.2.3 From 9ef4e520912e4966081e276beda628b69aac85dd Mon Sep 17 00:00:00 2001 From: Matthew Leung Date: Tue, 7 Jul 2026 20:32:49 +0000 Subject: phy: qcom: qmp-pcie: Add QMP PCIe PHY support for Hawi Add the QMP PCIe PHY support for the Gen3 x2 and Gen4 x1 PHY found on the Hawi platform. Signed-off-by: Matthew Leung Reviewed-by: Dmitry Baryshkov Link: https://patch.msgid.link/20260707-hawi-phy-pcie-v4-4-8d9cc6324947@oss.qualcomm.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 373 +++++++++++++++++++++++++++++++ 1 file changed, 373 insertions(+) (limited to 'drivers') diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c index 9f933eff3f12..357a2e2f8ff6 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c @@ -118,6 +118,20 @@ static const unsigned int pciephy_v8_50_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V8_50_PCS_POWER_DOWN_CONTROL, }; +static const unsigned int pciephy_v10_regs_layout[QPHY_LAYOUT_SIZE] = { + [QPHY_SW_RESET] = QPHY_V10_PCS_SW_RESET, + [QPHY_START_CTRL] = QPHY_V10_PCS_START_CONTROL, + [QPHY_PCS_STATUS] = QPHY_V10_PCS_PCS_STATUS1, + [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V10_PCS_POWER_DOWN_CONTROL, +}; + +static const unsigned int pciephy_v10_60_regs_layout[QPHY_LAYOUT_SIZE] = { + [QPHY_SW_RESET] = QPHY_V10_60_PCS_SW_RESET, + [QPHY_START_CTRL] = QPHY_V10_60_PCS_START_CONTROL, + [QPHY_PCS_STATUS] = QPHY_V10_60_PCS_PCS_STATUS1, + [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V10_60_PCS_POWER_DOWN_CONTROL, +}; + static const struct qmp_phy_init_tbl msm8998_pcie_serdes_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14), QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30), @@ -3328,6 +3342,287 @@ static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_pcs_misc_tbl[] = QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_POWER_STATE_CONFIG6, 0x1f), }; +static const struct qmp_phy_init_tbl hawi_qmp_gen3x2_pcie_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_EN_CENTER, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_PER1, 0x62), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_PER2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_STEP_SIZE1_MODE0, 0xf8), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_STEP_SIZE2_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_STEP_SIZE1_MODE1, 0x93), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_SSC_STEP_SIZE2_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_CLK_ENABLE1, 0x90), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_SYS_CLK_CTRL, 0x82), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_IVCO, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_CP_CTRL_MODE0, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_CP_CTRL_MODE1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_RCTRL_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_PLL_CCTRL_MODE1, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_SYSCLK_EN_SEL, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_BG_TIMER, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP_EN, 0x42), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP1_MODE0, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP2_MODE0, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP1_MODE1, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_LOCK_CMP2_MODE1, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_DEC_START_MODE0, 0x41), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_DEC_START_MODE1, 0x34), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START1_MODE0, 0xab), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START2_MODE0, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START3_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START1_MODE1, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START2_MODE1, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_DIV_FRAC_START3_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_VCO_TUNE_MAP, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_CLK_SELECT, 0x34), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_HSCLK_SEL_1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_CORECLK_DIV_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_CMN_CONFIG_1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_ADDITIONAL_MISC_3, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V10_COM_CORE_CLK_EN, 0xa0), +}; + +static const struct qmp_phy_init_tbl hawi_qmp_gen3x2_pcie_rx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V10_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_GM_CAL, 0x11), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_HIGH, 0xbf), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_HIGH2, 0xbf), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_HIGH3, 0xb7), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_HIGH4, 0xec), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_00_LOW, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_HIGH, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_HIGH2, 0x49), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_HIGH3, 0x1b), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_HIGH4, 0x9c), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_01_LOW, 0xd1), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_10_HIGH, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_10_HIGH2, 0x49), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_10_HIGH3, 0x1b), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_10_HIGH4, 0x9c), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_MODE_10_LOW, 0xd1), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_TX_ADAPT_PRE_THRESH1, 0x3e), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_TX_ADAPT_PRE_THRESH2, 0x1e), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_TX_ADAPT_POST_THRESH, 0xd2), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_FO_GAIN, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_SO_GAIN, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_SB2_THRESH1, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_UCDR_SB2_THRESH2, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_VGA_CAL_CNTRL2, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_SIGDET_ENABLES, 0x1c), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_SIGDET_CNTRL, 0x60), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_RX_IDAC_TSETTLE_LOW, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V10_RX_SIGDET_CAL_TRIM, 0x08), +}; + +static const struct qmp_phy_init_tbl hawi_qmp_gen3x2_pcie_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V10_TX_LANE_MODE_1, 0x25), + QMP_PHY_INIT_CFG(QSERDES_V10_TX_LANE_MODE_3, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V10_TX_LANE_MODE_4, 0x31), + QMP_PHY_INIT_CFG(QSERDES_V10_TX_LANE_MODE_5, 0x7d), + QMP_PHY_INIT_CFG(QSERDES_V10_TX_PI_QEC_CTRL, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V10_TX_RES_CODE_LANE_OFFSET_RX, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V10_TX_RES_CODE_LANE_OFFSET_TX, 0x14), +}; + +static const struct qmp_phy_init_tbl hawi_qmp_gen3x2_pcie_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V10_PCS_REFGEN_REQ_CONFIG1, 0x05), + QMP_PHY_INIT_CFG(QPHY_V10_PCS_RX_SIGDET_LVL, 0x77), + QMP_PHY_INIT_CFG(QPHY_V10_PCS_RATE_SLEW_CNTRL1, 0x0b), + QMP_PHY_INIT_CFG(QPHY_V10_PCS_EQ_CONFIG2, 0x0f), + QMP_PHY_INIT_CFG(QPHY_V10_PCS_PCS_TX_RX_CONFIG, 0x8c), + QMP_PHY_INIT_CFG(QPHY_V10_PCS_G12S1_TXDEEMPH_M6DB, 0x17), + QMP_PHY_INIT_CFG(QPHY_V10_PCS_G3S2_PRE_GAIN, 0x2e), +}; + +static const struct qmp_phy_init_tbl hawi_qmp_gen3x2_pcie_pcs_misc_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_PCS_EQ_CONFIG1, 0x1e), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_PCS_RXEQEVAL_TIME, 0x27), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_PCS_POWER_STATE_CONFIG2, 0x1d), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_PCS_POWER_STATE_CONFIG4, 0x07), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_PCS_POWER_STATE_CONFIG6, 0x1f), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_PCS_ENDPOINT_REFCLK_DRIVE, 0xc1), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_PCS_OSC_DTCT_ACTIONS, 0x00), +}; + +static const struct qmp_phy_init_tbl hawi_qmp_gen4x1_pcie_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_SSC_STEP_SIZE1_MODE1, 0x93), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_SSC_STEP_SIZE2_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CP_CTRL_MODE1, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_PLL_RCTRL_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_PLL_CCTRL_MODE1, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CORECLK_DIV_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_LOCK_CMP1_MODE1, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_LOCK_CMP2_MODE1, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_DEC_START_MODE1, 0x34), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_DIV_FRAC_START1_MODE1, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_DIV_FRAC_START2_MODE1, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_DIV_FRAC_START3_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_HSCLK_SEL_1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_SSC_STEP_SIZE1_MODE0, 0xf8), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_SSC_STEP_SIZE2_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CP_CTRL_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CORECLK_DIV_MODE0, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_LOCK_CMP1_MODE0, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_LOCK_CMP2_MODE0, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_DEC_START_MODE0, 0x41), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_DIV_FRAC_START1_MODE0, 0xab), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_DIV_FRAC_START2_MODE0, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_DIV_FRAC_START3_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_HSCLK_HS_SWITCH_SEL_1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_BG_TIMER, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_SSC_PER1, 0x62), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_SSC_PER2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_BIAS_EN_CLKBUFLR_EN, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CLK_ENABLE1, 0x90), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_SYS_CLK_CTRL, 0x82), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_PLL_IVCO, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_SYSCLK_EN_SEL, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_LOCK_CMP_EN, 0x46), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_LOCK_CMP_CFG, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_VCO_TUNE_MAP, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CLK_SELECT, 0x34), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CORE_CLK_EN, 0xa0), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CMN_CONFIG_1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CMN_MISC1, 0x88), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_CMN_MODE, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_VCO_DC_LEVEL_CTRL, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V10_60_COM_PLL_SPARE_FOR_ECO, 0x02), +}; + +static const struct qmp_phy_init_tbl hawi_qmp_gen4x1_pcie_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RES_CODE_LANE_OFFSET_TX, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RES_CODE_LANE_OFFSET_RX, 0x12), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SIGDET_CAL_CTRL1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SIGDET_CAL_CTRL2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SIGDET_CAL_TRIM, 0x66), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_TX_BAND0, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_TX_BAND1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SEL_10B_8B, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SEL_20B_10B, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_EQ_RCF_CTRL_RATE3, 0x22), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_EQ_RCF_CTRL_RATE4, 0x22), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_PHPRE_CTRL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FASTLOCK_FO_GAIN_RATE1, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FASTLOCK_FO_GAIN_RATE2, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FASTLOCK_FO_GAIN_RATE3, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FASTLOCK_SO_GAIN_RATE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FASTLOCK_SO_GAIN_RATE2, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FASTLOCK_SO_GAIN_RATE3, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_PI_CTRL1, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_PI_CTRL2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_PI_CTRL3, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_PI_CTRL4, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SVS_MODE_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RXCLK_DIV2_CTRL, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_BAND_CTRL0, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_TERM_BW_CTRL0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_TERM_BW_CTRL1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FO_GAIN_RATE1, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FO_GAIN_RATE2, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FO_GAIN_RATE3, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_FO_GAIN_RATE4, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_SO_GAIN_RATE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_SO_GAIN_RATE2, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_SO_GAIN_RATE3, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_SO_GAIN_RATE4, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_UCDR_PI_CONTROLS, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_AUXDATA_BIN_RATE3, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_AUXDATA_BIN_RATE4, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_EOM_MAX_ERR_LIMIT_LSB, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_EOM_MAX_ERR_LIMIT_MSB, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_VGA_CAL_CNTRL1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_VGA_CAL_MAN_VAL, 0x8e), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_GM_CAL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_EQU_ADAPTOR_CNTRL6, 0xca), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SIGDET_ENABLES, 0x1c), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SIGDET_CNTRL, 0x6f), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SIGDET_LVL, 0x84), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_SIGDET_DEGLITCH_CNTRL, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_Q_PI_INTRINSIC_BIAS_RATE32, 0x11), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_Q_PI_INTRINSIC_BIAS_RATE45, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B0, 0xc2), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B1, 0xc2), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B2, 0xd8), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B3, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B4, 0x98), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B5, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B6, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B7, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B8, 0xc0), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B9, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE_0_1_B10, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B0, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B1, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B2, 0xd8), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B3, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B4, 0x98), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B5, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B6, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B7, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B8, 0xc0), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B9, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE2_B10, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B0, 0x13), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B1, 0xd3), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B2, 0xc0), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B3, 0x13), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B4, 0x13), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B5, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B6, 0x4c), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B7, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B8, 0xc0), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B9, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE3_B10, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B0, 0x24), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B1, 0x24), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B2, 0xc0), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B3, 0x0b), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B4, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B5, 0x24), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B6, 0x2c), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B7, 0x86), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B8, 0x83), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B9, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_RX_MODE_RATE4_SA_B10, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_LANE_MODE_1, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_LANE_MODE_2, 0xc0), + QMP_PHY_INIT_CFG(QSERDES_V10_60_TXRX_LANE_MODE_3, 0x00), +}; + +static const struct qmp_phy_init_tbl hawi_qmp_gen4x1_pcie_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V10_60_PCS_G12S1_TXDEEMPH_M6DB, 0x17), + QMP_PHY_INIT_CFG(QPHY_V10_60_PCS_G3S2_PRE_GAIN, 0x2e), + QMP_PHY_INIT_CFG(QPHY_V10_60_PCS_RX_SIGDET_LVL, 0xcc), + QMP_PHY_INIT_CFG(QPHY_V10_60_PCS_ELECIDLE_DLY_SEL, 0x40), + QMP_PHY_INIT_CFG(QPHY_V10_60_PCS_PCS_TX_RX_CONFIG1, 0x04), + QMP_PHY_INIT_CFG(QPHY_V10_60_PCS_PCS_TX_RX_CONFIG2, 0x02), + QMP_PHY_INIT_CFG(QPHY_V10_60_PCS_EQ_CONFIG4, 0x00), + QMP_PHY_INIT_CFG(QPHY_V10_60_PCS_EQ_CONFIG5, 0x22), +}; + +static const struct qmp_phy_init_tbl hawi_qmp_gen4x1_pcie_pcs_misc_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_POWER_STATE_CONFIG2, 0x1d), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_TX_RX_CONFIG, 0xc0), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_ENDPOINT_REFCLK_DRIVE, 0xc1), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_OSC_DTCT_ACTIONS, 0x00), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_EQ_CONFIG1, 0x16), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_G3_RXEQEVAL_TIME, 0x27), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_G4_RXEQEVAL_TIME, 0x27), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_G4_EQ_CONFIG5, 0x02), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_G4_PRE_GAIN, 0x2e), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_RX_MARGINING_CONFIG1, 0x03), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_RX_MARGINING_CONFIG3, 0x28), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_RX_MARGINING_CONFIG5, 0x0f), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_G3_FOM_EQ_CONFIG5, 0xf2), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_G4_FOM_EQ_CONFIG5, 0xf2), + QMP_PHY_INIT_CFG(QPHY_PCIE_V10_60_PCS_POWER_STATE_CONFIG6, 0x1f), +}; + struct qmp_pcie_offsets { u16 serdes; u16 pcs; @@ -3640,6 +3935,24 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v8_50 = { .txrxz = 0xd000, }; +static const struct qmp_pcie_offsets qmp_pcie_offsets_v10_0 = { + .serdes = 0x0000, + .pcs = 0x0400, + .pcs_misc = 0x0800, + .tx = 0x1000, + .rx = 0x1200, + .tx2 = 0x1800, + .rx2 = 0x1a00, +}; + +static const struct qmp_pcie_offsets qmp_pcie_offsets_v10_60 = { + .tx = 0x0000, + /* no .rx; tx and rx share the same register block */ + .serdes = 0x1000, + .pcs = 0x1400, + .pcs_misc = 0x1800, +}; + static const struct qmp_phy_cfg eliza_qmp_gen3x1_pciephy_cfg = { .lanes = 1, @@ -4783,6 +5096,60 @@ static const struct qmp_phy_cfg glymur_qmp_gen4x2_pciephy_cfg = { .phy_status = PHYSTATUS_4_20, }; +static const struct qmp_phy_cfg hawi_qmp_gen3x2_pciephy_cfg = { + .lanes = 2, + + .offsets = &qmp_pcie_offsets_v10_0, + + .tbls = { + .serdes = hawi_qmp_gen3x2_pcie_serdes_tbl, + .serdes_num = ARRAY_SIZE(hawi_qmp_gen3x2_pcie_serdes_tbl), + .tx = hawi_qmp_gen3x2_pcie_tx_tbl, + .tx_num = ARRAY_SIZE(hawi_qmp_gen3x2_pcie_tx_tbl), + .rx = hawi_qmp_gen3x2_pcie_rx_tbl, + .rx_num = ARRAY_SIZE(hawi_qmp_gen3x2_pcie_rx_tbl), + .pcs = hawi_qmp_gen3x2_pcie_pcs_tbl, + .pcs_num = ARRAY_SIZE(hawi_qmp_gen3x2_pcie_pcs_tbl), + .pcs_misc = hawi_qmp_gen3x2_pcie_pcs_misc_tbl, + .pcs_misc_num = ARRAY_SIZE(hawi_qmp_gen3x2_pcie_pcs_misc_tbl), + }, + + .reset_list = sdm845_pciephy_reset_l, + .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), + .vreg_list = qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .regs = pciephy_v10_regs_layout, + + .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, + .phy_status = PHYSTATUS, +}; + +static const struct qmp_phy_cfg hawi_qmp_gen4x1_pciephy_cfg = { + .lanes = 1, + + .offsets = &qmp_pcie_offsets_v10_60, + + .tbls = { + .serdes = hawi_qmp_gen4x1_pcie_serdes_tbl, + .serdes_num = ARRAY_SIZE(hawi_qmp_gen4x1_pcie_serdes_tbl), + .tx = hawi_qmp_gen4x1_pcie_tx_tbl, + .tx_num = ARRAY_SIZE(hawi_qmp_gen4x1_pcie_tx_tbl), + .pcs = hawi_qmp_gen4x1_pcie_pcs_tbl, + .pcs_num = ARRAY_SIZE(hawi_qmp_gen4x1_pcie_pcs_tbl), + .pcs_misc = hawi_qmp_gen4x1_pcie_pcs_misc_tbl, + .pcs_misc_num = ARRAY_SIZE(hawi_qmp_gen4x1_pcie_pcs_misc_tbl), + }, + + .reset_list = sdm845_pciephy_reset_l, + .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), + .vreg_list = qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .regs = pciephy_v10_60_regs_layout, + + .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, + .phy_status = PHYSTATUS_4_20, +}; + static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls) { const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -5545,6 +5912,12 @@ 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,hawi-qmp-gen3x2-pcie-phy", + .data = &hawi_qmp_gen3x2_pciephy_cfg, + }, { + .compatible = "qcom,hawi-qmp-gen4x1-pcie-phy", + .data = &hawi_qmp_gen4x1_pciephy_cfg, }, { .compatible = "qcom,ipq6018-qmp-pcie-phy", .data = &ipq6018_pciephy_cfg, -- cgit v1.2.3 From f40b0241f3a382e99c14de2f28f14a44973407c1 Mon Sep 17 00:00:00 2001 From: Can Peng Date: Sat, 18 Jul 2026 17:00:53 +0800 Subject: phy: starfive: Fix runtime PM cleanup in JH7110 DPHY TX probe stf_dphy_probe() enables runtime PM before getting the clock and reset controls, creating the PHY and registering the PHY provider. If any of those steps fails, probe returns with runtime PM still enabled. The driver also has no remove callback, so runtime PM is left enabled on driver unbind after a successful probe. Use devm_pm_runtime_enable() so runtime PM is disabled automatically on later probe failures and on driver unbind. Fixes: d3ab79553308 ("phy: starfive: Add mipi dphy tx support") Signed-off-by: Can Peng Reviewed-by: Changhuang Liang Link: https://patch.msgid.link/20260718090054.444513-2-pengcan@kylinos.cn Signed-off-by: Vinod Koul --- drivers/phy/starfive/phy-jh7110-dphy-tx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/phy/starfive/phy-jh7110-dphy-tx.c b/drivers/phy/starfive/phy-jh7110-dphy-tx.c index c64d1c91b130..181491a93807 100644 --- a/drivers/phy/starfive/phy-jh7110-dphy-tx.c +++ b/drivers/phy/starfive/phy-jh7110-dphy-tx.c @@ -392,6 +392,7 @@ static int stf_dphy_probe(struct platform_device *pdev) { struct phy_provider *phy_provider; struct stf_dphy *dphy; + int ret; dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL); if (!dphy) @@ -406,7 +407,9 @@ static int stf_dphy_probe(struct platform_device *pdev) if (IS_ERR(dphy->topsys)) return PTR_ERR(dphy->topsys); - pm_runtime_enable(&pdev->dev); + ret = devm_pm_runtime_enable(&pdev->dev); + if (ret) + return ret; dphy->txesc_clk = devm_clk_get(&pdev->dev, "txesc"); if (IS_ERR(dphy->txesc_clk)) -- cgit v1.2.3 From 97bed336f6a25c9d1115ca95e3aa00e05c3bc271 Mon Sep 17 00:00:00 2001 From: Can Peng Date: Sat, 18 Jul 2026 17:00:54 +0800 Subject: phy: starfive: Fix runtime PM cleanup in JH7110 DPHY RX probe stf_dphy_probe() enables runtime PM before registering the PHY provider. If devm_of_phy_provider_register() fails, probe returns with runtime PM still enabled. The driver also has no remove callback, so runtime PM is left enabled on driver unbind after a successful probe. Use devm_pm_runtime_enable() so runtime PM is disabled automatically on later probe failures and on driver unbind. Fixes: f8aa660841bc ("phy: starfive: Add mipi dphy rx support") Signed-off-by: Can Peng Reviewed-by: Changhuang Liang Link: https://patch.msgid.link/20260718090054.444513-3-pengcan@kylinos.cn Signed-off-by: Vinod Koul --- drivers/phy/starfive/phy-jh7110-dphy-rx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/phy/starfive/phy-jh7110-dphy-rx.c b/drivers/phy/starfive/phy-jh7110-dphy-rx.c index 0b039e1f71c5..d06f21ad6332 100644 --- a/drivers/phy/starfive/phy-jh7110-dphy-rx.c +++ b/drivers/phy/starfive/phy-jh7110-dphy-rx.c @@ -150,6 +150,7 @@ static int stf_dphy_probe(struct platform_device *pdev) { struct phy_provider *phy_provider; struct stf_dphy *dphy; + int ret; dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL); if (!dphy) @@ -190,7 +191,9 @@ static int stf_dphy_probe(struct platform_device *pdev) return PTR_ERR(dphy->phy); } - pm_runtime_enable(&pdev->dev); + ret = devm_pm_runtime_enable(&pdev->dev); + if (ret) + return ret; phy_set_drvdata(dphy->phy, dphy); phy_provider = devm_of_phy_provider_register(&pdev->dev, -- cgit v1.2.3 From 7a099760ea63ced7b194852b7dbbdcd951585f15 Mon Sep 17 00:00:00 2001 From: Inochi Amaoto Date: Fri, 3 Jul 2026 10:10:23 +0800 Subject: phy: spacemit: Add USB3/PCIe comb PHY driver for Spacemit K3 The comb PHY on K3 requires to configure a syscon device for the right mux configuration. And it requires calibration before any usage. Add USB3/PCIe comb PHY driver for Spacemit K3. Signed-off-by: Inochi Amaoto Tested-by: Aurelien Jarno Link: https://patch.msgid.link/20260703021024.495433-3-inochiama@gmail.com Signed-off-by: Vinod Koul --- drivers/phy/spacemit/Kconfig | 16 ++ drivers/phy/spacemit/Makefile | 2 + drivers/phy/spacemit/phy-k3-combo.c | 252 ++++++++++++++++++++++ drivers/phy/spacemit/phy-k3-common.c | 391 +++++++++++++++++++++++++++++++++++ drivers/phy/spacemit/phy-k3-common.h | 27 +++ 5 files changed, 688 insertions(+) create mode 100644 drivers/phy/spacemit/phy-k3-combo.c create mode 100644 drivers/phy/spacemit/phy-k3-common.c create mode 100644 drivers/phy/spacemit/phy-k3-common.h (limited to 'drivers') diff --git a/drivers/phy/spacemit/Kconfig b/drivers/phy/spacemit/Kconfig index 50b0005acf66..5fdf18fce499 100644 --- a/drivers/phy/spacemit/Kconfig +++ b/drivers/phy/spacemit/Kconfig @@ -23,3 +23,19 @@ config PHY_SPACEMIT_K1_USB2 help Enable this to support K1 USB 2.0 PHY driver. This driver takes care of enabling and clock setup and will be used by K1 udc/ehci/otg/xhci driver. + +config PHY_SPACEMIT_K3_COMMON_OPS + tristate + select MFD_SYSCON + select GENERIC_PHY + +config PHY_SPACEMIT_K3_COMBO_PHY + tristate "SpacemiT K3 USB3/PCIe PHY support" + depends on (ARCH_SPACEMIT || COMPILE_TEST) && OF + depends on COMMON_CLK + select PHY_SPACEMIT_K3_COMMON_OPS + help + Enable this to support K3 USB3/PCIe combo PHY driver. This + driver takes care of enabling and clock setup and will be used + by K3 dwc3 driver. + If unsure, say N. diff --git a/drivers/phy/spacemit/Makefile b/drivers/phy/spacemit/Makefile index a821a21d6142..f679c1851b4f 100644 --- a/drivers/phy/spacemit/Makefile +++ b/drivers/phy/spacemit/Makefile @@ -1,3 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_PHY_SPACEMIT_K1_PCIE) += phy-k1-pcie.o obj-$(CONFIG_PHY_SPACEMIT_K1_USB2) += phy-k1-usb2.o +obj-$(CONFIG_PHY_SPACEMIT_K3_COMBO_PHY) += phy-k3-combo.o +obj-$(CONFIG_PHY_SPACEMIT_K3_COMMON_OPS) += phy-k3-common.o diff --git a/drivers/phy/spacemit/phy-k3-combo.c b/drivers/phy/spacemit/phy-k3-combo.c new file mode 100644 index 000000000000..0bc08bb6247a --- /dev/null +++ b/drivers/phy/spacemit/phy-k3-combo.c @@ -0,0 +1,252 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * phy-k3-combo.c - SpacemiT K3 PCIe/USB3 Combo PHY Driver + * + * Copyright (c) 2025 SpacemiT Technology Co. Ltd + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "phy-k3-common.h" + +/* + * The PCIE/USB Subsystem on SpacemiT K3 have 3 single lane PIPE3 PHYs + * (PHY2/3/4) shared by PCIE PortC/D and USB3 PortB/C/D. + * + * PMUA_PCIE_SUBSYS_MGMT[4:0] + * + * bit4 = 0 : PCIe A X8 mode, all 8 lanes dedicated to PCIe Port A + * 1 : PHY lanes shared between PCIe or USB according to [3:0] + * + * All PHY matrix combinations according to [4:0]: + * + * 0x0X : PCIe-A X8 + * 0x10 : PCIe-C x2 (PHY2+PHY3) + PCIe-D x1 (PHY4) + * 0x11 : PCIe-C x2 (PHY2+PHY3) + USB-D (PHY4) + * 0x12 : PCIe-C x1 (PHY2) + USB-C (PHY3) + * 0x13 : PCIe-C x1 (PHY2) + USB-C (PHY3) + USB-D (PHY4) + * 0x14 : PCIe-C x1 (PHY3) + USB-B (PHY2) + * 0x15 : PCIe-C x1 (PHY3) + USB-B (PHY2) + USB-D (PHY4) + * 0x16 : USB-B (PHY2) + USB-C (PHY3) + PCIe D x1 (PHY4) + * 0x17 : USB-B (PHY2) + USB-C (PHY3) + USB-D (PHY4) + * + * So any USB Port B/C/D operation requires PCIe A X8 mode to be disabled. + */ +#define PMUA_PCIE_SUBSYS_MGMT 0x1d8 +#define PU_MATRIX_CONF_MASK GENMASK(4, 0) + +#define COMBPHY_MAX_SUBPHYS 6 + +struct k3_combo_phy { + struct device *dev; + struct k3_lane_group groups[COMBPHY_MAX_SUBPHYS]; + void __iomem *base; + struct regmap *apb_spare; +}; + +static const struct k3_phy_lane_group_data k3_combphy_lane_group0 = { + .lanes = 2, + .config = 0xff, + .mask = 0x00, + .offsets = { + 0x0, 0x400 + }, +}; + +static const struct k3_phy_lane_group_data k3_combphy_lane_group1 = { + .lanes = 2, + .config = 0xff, + .mask = 0x00, + .offsets = { + 0x100000, 0x100400 + }, +}; + +static const struct k3_phy_lane_group_data k3_combphy_lane_group2 = { + .lanes = 1, + .config = 0x14, + .mask = 0x14, + .offsets = { + 0x200000 + }, +}; + +static const struct k3_phy_lane_group_data k3_combphy_lane_group3 = { + .lanes = 1, + .config = 0x12, + .mask = 0x12, + .offsets = { + 0x300000 + }, +}; + +static const struct k3_phy_lane_group_data k3_combphy_lane_group4 = { + .lanes = 1, + .config = 0x11, + .mask = 0x11, + .offsets = { + 0x400000 + }, +}; + +static const struct k3_phy_lane_group_data k3_combphy_lane_group5 = { + .lanes = 1, + .config = 0xff, + .mask = 0x00, + .offsets = { + 0x500000 + }, +}; + +static const struct k3_phy_lane_group_data *k3_combphy_lane_datas[] = { + &k3_combphy_lane_group0, + &k3_combphy_lane_group1, + &k3_combphy_lane_group2, + &k3_combphy_lane_group3, + &k3_combphy_lane_group4, + &k3_combphy_lane_group5, +}; + +static int k3_combo_phy_init_lanes(struct k3_combo_phy *phy, unsigned int config) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(k3_combphy_lane_datas); i++) { + const struct k3_phy_lane_group_data *data = k3_combphy_lane_datas[i]; + struct k3_lane_group *lg = &phy->groups[i]; + const struct phy_ops *ops; + bool is_usb; + + is_usb = (data->mask & config) == data->config; + if (is_usb) + ops = &k3_usb3_phy_ops; + else + ops = &k3_pcie_phy_ops; + + dev_dbg(phy->dev, "phy %d is %s\n", i, is_usb ? "usb" : "pcie"); + + lg->phy = devm_phy_create(phy->dev, NULL, ops); + if (IS_ERR(lg->phy)) + return PTR_ERR(lg->phy); + + lg->is_pcie = !is_usb; + lg->data = data; + lg->base = phy->base; + phy_set_drvdata(lg->phy, lg); + } + + return 0; +} + +static int k3_combo_phy_update_config(struct regmap *apmu, unsigned int config) +{ + if (config & ~PU_MATRIX_CONF_MASK) + return -EINVAL; + + return regmap_update_bits(apmu, PMUA_PCIE_SUBSYS_MGMT, PU_MATRIX_CONF_MASK, config); +} + +static struct phy *k3_combo_phy_xlate(struct device *dev, const struct of_phandle_args *args) +{ + struct k3_combo_phy *phy = dev_get_drvdata(dev); + struct k3_lane_group *lg; + + if (args->args_count != 2) { + dev_err(dev, "Invalid number of arguments\n"); + return ERR_PTR(-EINVAL); + } + + if (args->args[0] >= ARRAY_SIZE(k3_combphy_lane_datas)) { + dev_err(dev, "Invalid PHY id\n"); + return ERR_PTR(-EINVAL); + } + + lg = &phy->groups[args->args[0]]; + + if ((lg->is_pcie && args->args[1] != PHY_TYPE_PCIE) || + (!lg->is_pcie && args->args[1] != PHY_TYPE_USB3)) { + dev_err(dev, "Invalid PHY mode\n"); + return ERR_PTR(-EINVAL); + } + + return lg->phy; +} + +static int k3_combo_phy_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + struct phy_provider *provider; + struct k3_combo_phy *phy; + struct regmap *apmu; + u32 config = 0; + int ret; + + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); + if (!phy) + return -ENOMEM; + + phy->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(phy->base)) + return PTR_ERR(phy->base); + + phy->apb_spare = syscon_regmap_lookup_by_phandle(node, "spacemit,apb-spare"); + if (IS_ERR(phy->apb_spare)) + return dev_err_probe(dev, PTR_ERR(phy->apb_spare), + "Failed to find APB SPARE syscon"); + + apmu = syscon_regmap_lookup_by_phandle_args(node, "spacemit,apmu", 1, &config); + if (IS_ERR(apmu)) + return dev_err_probe(dev, PTR_ERR(apmu), + "Failed to find APMU syscon"); + + ret = k3_combo_phy_update_config(apmu, config); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to set lane configuration"); + + phy->dev = dev; + platform_set_drvdata(pdev, phy); + + ret = k3_phy_calibrate(phy->apb_spare); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to calibrate phy"); + + ret = k3_combo_phy_init_lanes(phy, config); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to init lanes"); + + provider = devm_of_phy_provider_register(dev, k3_combo_phy_xlate); + if (IS_ERR(provider)) + return dev_err_probe(dev, PTR_ERR(provider), + "Failed to register provider\n"); + + return 0; +} + +static const struct of_device_id k3_combo_phy_of_match[] = { + { .compatible = "spacemit,k3-combo-phy" }, + { }, +}; +MODULE_DEVICE_TABLE(of, k3_combo_phy_of_match); + +static struct platform_driver k3_combo_phy_driver = { + .probe = k3_combo_phy_probe, + .driver = { + .name = "spacemit,k3-combo-phy", + .of_match_table = k3_combo_phy_of_match, + }, +}; +module_platform_driver(k3_combo_phy_driver); + +MODULE_DESCRIPTION("SpacemiT K3 USB3/PCIe combo PHY driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/phy/spacemit/phy-k3-common.c b/drivers/phy/spacemit/phy-k3-common.c new file mode 100644 index 000000000000..0b289e63db99 --- /dev/null +++ b/drivers/phy/spacemit/phy-k3-common.c @@ -0,0 +1,391 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "phy-k3-common.h" + +/* PHY Registers */ +#define PHY_VERSION 0x0 + +#define PHY_RESET_CFG 0x04 + +#define PHY_RESET_RXBUF_RST BIT(0) +#define PHY_RESET_SOFT_RST_PCS BIT(1) +#define PHY_RESET_SOFT_RST_AHB BIT(2) +#define PHY_RESET_EN_SD_AFTER_LOCK BIT(6) + +#define PHY_CLK_CFG 0x08 + +#define PHY_CLK_PLL_READY BIT(0) +#define PHY_CLK_TXCLK_INV BIT(2) +#define PHY_CLK_RXCLK_EN BIT(3) +#define PHY_CLK_TXCLK_EN BIT(4) +#define PHY_CLK_PCLK_EN BIT(5) +#define PHY_CLK_PIPE_PCLK_EN BIT(6) +#define PHY_CLK_REFCLK_FREQ GENMASK(10, 7) +#define PHY_CLK_REFCLK_24M 2 +#define PHY_CLK_SW_INIT_DONE BIT(11) +#define PHY_CLK_PU_SSC_OUT BIT(23) + +#define PHY_MODE_CFG 0x0C + +#define PHY_MODE_PCIE_INT_EN BIT(0) +#define PHY_MODE_LFPS_TPERIOD GENMASK(9, 8) +#define PHY_MODE_LFPS_TPERIOD_USB 3 + +#define PHY_PU_SEL 0x40 + +#define PHY_PU_CFG_STATUS BIT(9) +#define PHY_PU_OVRD_STATUS BIT(10) + +#define PHY_PU_CK_REG 0x54 + +#define PHY_PU_REFCLK_100 BIT(25) + +#define PHY_PLL_REG1 0x58 + +#define PHY_PLL_FREF_SEL GENMASK(15, 13) +#define PHY_PLL_FREF_24M 0x1 +#define PHY_PLL_SSC_DEP_SEL GENMASK(27, 24) +#define PHY_PLL_SSC_5000PPM 0xa +#define PHY_PLL_SSC_MODE GENMASK(29, 28) +#define PHY_PLL_SSC_MODE_CENTER_SPREAD 0 +#define PHY_PLL_SSC_MODE_UP_SPREAD 1 +#define PHY_PLL_SSC_MODE_DOWN_SPREAD 2 +#define PHY_PLL_SSC_MODE_DOWN_SPREAD1 3 + +#define PHY_PLL_REG2 0x5c + +#define PHY_PLL_SEL_REF100 BIT(21) + +/* PHY RX Register Definitions */ +#define PHY_RX_REG_A 0x60 + +#define PHY_RX_REG0_MASK GENMASK(7, 0) +#define PHY_RX_REG1_MASK GENMASK(15, 8) +#define PHY_RX_REG2_MASK GENMASK(23, 16) +#define PHY_RX_REG3_MASK GENMASK(31, 24) + +#define PHY_RX_REG0_RLOAD BIT(4) +#define PHY_RX_REG1_RTERM GENMASK(11, 8) +#define PHY_RX_REG1_RC_CALI GENMASK(15, 12) +#define PHY_RX_REG2_CSEL GENMASK(19, 16) +#define PHY_RX_REG2_FORCE_CSEL BIT(20) +#define PHY_RX_REG2_PSEL GENMASK(23, 21) +#define PHY_RX_REG3_I_LOAD GENMASK(26, 24) +#define PHY_RX_REG3_SEL_CBOOST_CODE BIT(27) +#define PHY_RX_REG3_ADJ_BIAS GENMASK(29, 28) +#define PHY_RX_REG3_RDEG1 GENMASK(31, 30) + +#define PHY_RX_REG_B 0x64 + +#define PHY_RX_REG4_MASK GENMASK(7, 0) +#define PHY_RX_REG5_MASK GENMASK(15, 8) +#define PHY_RX_REG6_MASK GENMASK(23, 16) + +#define PHY_RX_REGB_MASK GENMASK(23, 0) + +#define PHY_RX_REG4_RDEG2 GENMASK(2, 1) +#define PHY_RX_REG4_ENVOS BIT(4) +#define PHY_RX_REG4_RTERM_SEL BIT(5) +#define PHY_RX_REG4_MANUAL_CFG BIT(7) +#define PHY_RX_REG5_RCELL_VCM GENMASK(11, 8) +#define PHY_RX_REG5_RCELL_BIAS GENMASK(15, 12) +#define PHY_RX_REG6_H1_REG GENMASK(19, 16) +#define PHY_RX_REG6_ADAPT_GAIN GENMASK(21, 20) +#define PHY_RX_REG6_BYPASS_ADPT BIT(22) + +#define PHY_ADPT_CFG0 0x140 +#define PHY_ADPT_AFE_RST_OVRD_EN BIT(1) +#define PHY_ADPT_AFE_RST_OVRD_VAL BIT(4) + +#define PHY_RXEQ_TIME 0xb4 +#define PHY_RXEQ_TIME_OVRD_POST_C_SOC BIT(21) +#define PHY_RXEQ_TIME_CFG_AMP_SOC GENMASK(23, 22) +#define PHY_RXEQ_TIME_AMP_SOC_650M 0 +#define PHY_RXEQ_TIME_AMP_SOC_800M 1 +#define PHY_RXEQ_TIME_AMP_SOC_870M 2 +#define PHY_RXEQ_TIME_AMP_SOC_900M 3 +#define PHY_RXEQ_TIME_OVRD_AMP_SOC BIT(24) + +#define PCIE_PU_ADDR_CLK_CFG 0x0008 +#define PHY_CLK_PLL_READY BIT(0) +#define PCIE_INITAL_TIMER GENMASK(6, 3) +#define CFG_INTERNAL_TIMER_ADJ GENMASK(10, 7) +#define CFG_SW_PHY_INIT_DONE BIT(11) + +/* Lane RX/TX configuration (per‑lane, at lane_base) */ +#define PCIE_RX_REG1 0x050 +#define PCIE_RX_REFCLK_MODE GENMASK(1, 0) +#define PCIE_RX_REFCLK_MODE_DRIVER 1 +#define PCIE_RX_SEL_TRI_CODE BIT(2) +#define PCIE_RX_LEGACY GENMASK(15, 8) +#define PCIE_RX_LEGACY_DEFAULT 0x65 + +#define PCIE_TX_REG1 0x064 + +#define PCIE_PLL_TIMEOUT 500000 +#define PCIE_POLL_DELAY 500 + +static int k3_usb3phy_init_single(struct k3_lane_group *lg, void __iomem *base) +{ + struct phy *phy = lg->phy; + u32 val, tmp; + int ret; + + /* Do not wait CDR lock before sampling data */ + val = readl(base + PHY_RESET_CFG); + val = u32_replace_bits(val, 0, PHY_RESET_EN_SD_AFTER_LOCK); + writel(val, base + PHY_RESET_CFG); + + /* Power down 100MHz refclk buffer */ + val = readl(base + PHY_PU_CK_REG); + val = u32_replace_bits(val, 0, PHY_PU_REFCLK_100); + writel(val, base + PHY_PU_CK_REG); + + /* Program PLL REG1 configure the SSC */ + val = FIELD_PREP(PHY_PLL_SSC_MODE, PHY_PLL_SSC_MODE_DOWN_SPREAD1) | + FIELD_PREP(PHY_PLL_SSC_DEP_SEL, PHY_PLL_SSC_5000PPM) | + FIELD_PREP(PHY_PLL_FREF_SEL, PHY_PLL_FREF_24M); + writel(val, base + PHY_PLL_REG1); + + /* Un-select 100MHz PLL reference */ + val = readl(base + PHY_PLL_REG2); + val = u32_replace_bits(val, 0, PHY_PLL_SEL_REF100); + writel(val, base + PHY_PLL_REG2); + + /* USB LFPS period configuration */ + val = readl(base + PHY_MODE_CFG); + val = u32_replace_bits(val, PHY_MODE_LFPS_TPERIOD_USB, PHY_MODE_LFPS_TPERIOD); + writel(val, base + PHY_MODE_CFG); + + /* Force AFE adaptation reset */ + val = readl(base + PHY_ADPT_CFG0); + val |= PHY_ADPT_AFE_RST_OVRD_EN | PHY_ADPT_AFE_RST_OVRD_VAL; + writel(val, base + PHY_ADPT_CFG0); + + /* Override driver amplitude value to 900m */ + val = readl(base + PHY_RXEQ_TIME); + val |= PHY_RXEQ_TIME_OVRD_AMP_SOC; + val = u32_replace_bits(val, PHY_RXEQ_TIME_AMP_SOC_900M, PHY_RXEQ_TIME_CFG_AMP_SOC); + writel(val, base + PHY_RXEQ_TIME); + + /* Configure RX parameters */ + val = PHY_RX_REG0_RLOAD | + FIELD_PREP(PHY_RX_REG1_RTERM, 0x8) | + FIELD_PREP(PHY_RX_REG1_RC_CALI, 0x7) | + FIELD_PREP(PHY_RX_REG2_CSEL, 0x8) | + PHY_RX_REG2_FORCE_CSEL | + FIELD_PREP(PHY_RX_REG2_PSEL, 0x4) | + FIELD_PREP(PHY_RX_REG3_I_LOAD, 0x7) | + PHY_RX_REG3_SEL_CBOOST_CODE | + FIELD_PREP(PHY_RX_REG3_ADJ_BIAS, 0x1) | + FIELD_PREP(PHY_RX_REG3_RDEG1, 0x3); + writel(val, base + PHY_RX_REG_A); + + val = readl(base + PHY_RX_REG_B); + tmp = FIELD_PREP(PHY_RX_REG4_RDEG2, 0x2) | + PHY_RX_REG4_ENVOS | PHY_RX_REG4_RTERM_SEL | PHY_RX_REG4_MANUAL_CFG | + FIELD_PREP(PHY_RX_REG5_RCELL_VCM, 0x8) | + FIELD_PREP(PHY_RX_REG5_RCELL_BIAS, 0x8) | + FIELD_PREP(PHY_RX_REG6_H1_REG, 0x8) | + FIELD_PREP(PHY_RX_REG6_ADAPT_GAIN, 0x2); + val = u32_replace_bits(val, tmp, PHY_RX_REGB_MASK); + writel(val, base + PHY_RX_REG_B); + + /* + * Inform PHY that all PLL-related configuration is done. + * PLL will not start locking until PHY_CLK_SW_INIT_DONE is set. + */ + val = PHY_CLK_SW_INIT_DONE | PHY_CLK_PU_SSC_OUT | + FIELD_PREP(PHY_CLK_REFCLK_FREQ, PHY_CLK_REFCLK_24M) | + PHY_CLK_RXCLK_EN | PHY_CLK_TXCLK_EN | + PHY_CLK_PCLK_EN | PHY_CLK_PIPE_PCLK_EN; + writel(val, base + PHY_CLK_CFG); + + ret = readl_poll_timeout(base + PHY_CLK_CFG, val, + (val & PHY_CLK_PLL_READY), + PCIE_POLL_DELAY, PCIE_PLL_TIMEOUT); + if (ret) { + dev_err(&phy->dev, "PHY PLL polling timeout\n"); + return ret; + } + + return 0; +} + +static int k3_usb3phy_init(struct phy *phy) +{ + struct k3_lane_group *lg = phy_get_drvdata(phy); + int ret, i; + + for (i = 0; i < lg->data->lanes; i++) { + ret = k3_usb3phy_init_single(lg, lg->base + lg->data->offsets[i]); + if (ret < 0) + return ret; + } + + return 0; +} + +const struct phy_ops k3_usb3_phy_ops = { + .init = k3_usb3phy_init, + .owner = THIS_MODULE, +}; +EXPORT_SYMBOL_GPL(k3_usb3_phy_ops); + +static int k3_pcie_phy_init(struct phy *phy) +{ + struct k3_lane_group *lg = phy_get_drvdata(phy); + void __iomem *phy_base = lg->base + lg->data->offsets[0]; + u32 val; + int ret; + int i; + + val = readl(phy_base + PHY_PLL_REG1); + val = u32_replace_bits(val, 0x2, GENMASK(15, 12)); + writel(val, phy_base + PHY_PLL_REG1); + + val = readl(phy_base + PHY_PLL_REG2); + val = u32_replace_bits(val, 0, BIT(21)); + writel(val, phy_base + PHY_PLL_REG2); + + for (i = 0; i < lg->data->lanes; i++) { + void __iomem *lane_base = lg->base + lg->data->offsets[i]; + + val = readl(lane_base + PCIE_RX_REG1); + val = u32_replace_bits(val, 0, 0x3); + writel(val, lane_base + PCIE_RX_REG1); + } + + val = readl(phy_base + PHY_PLL_REG2); + val |= BIT(20); + writel(val, phy_base + PHY_PLL_REG2); + + /* The write is needed as clock requires renegotiation */ + val = FIELD_PREP(PCIE_RX_REFCLK_MODE, PCIE_RX_REFCLK_MODE_DRIVER) | + PCIE_RX_SEL_TRI_CODE | + FIELD_PREP(PCIE_RX_LEGACY, PCIE_RX_LEGACY_DEFAULT); + writel(val, phy_base + PCIE_RX_REG1); + + /* pll_reg1 of lane0, disable SSC: pll[27:24] = 0 */ + val = readl(phy_base + PHY_PLL_REG1); + val = u32_replace_bits(val, 0, GENMASK(27, 24)); + writel(val, phy_base + PHY_PLL_REG1); + + for (i = 0; i < lg->data->lanes; i++) { + void __iomem *lane_base = lg->base + lg->data->offsets[i]; + + /* set cfg_tx_send_dummy_data to be 1'b1 for disable dash data */ + val = readl(lane_base + PHY_PU_SEL); + val = u32_replace_bits(val, 1, BIT(13)); + writel(val, lane_base + PHY_PU_SEL); + + /* disable en_sample_data_after_cdr_locked */ + val = readl(lane_base + PHY_RESET_CFG); + val = u32_replace_bits(val, 0, BIT(6)); + writel(val, lane_base + PHY_RESET_CFG); + + /* Dynamic Lock */ + val = readl(lane_base + PHY_MODE_CFG); + val = u32_replace_bits(val, 1, BIT(2)); + writel(val, lane_base + PHY_MODE_CFG); + + val = FIELD_PREP(PHY_RX_REG0_MASK, 0x10) | + FIELD_PREP(PHY_RX_REG1_MASK, 0x78) | + FIELD_PREP(PHY_RX_REG2_MASK, 0x98) | + FIELD_PREP(PHY_RX_REG3_MASK, 0xdf); + writel(val, lane_base + PHY_RX_REG_A); + + val = readl(lane_base + PHY_RX_REG_B); + val &= ~PHY_RX_REGB_MASK; + val |= FIELD_PREP(PHY_RX_REG4_MASK, 0xb4) | + FIELD_PREP(PHY_RX_REG5_MASK, 0x88) | + FIELD_PREP(PHY_RX_REG6_MASK, 0x28); + writel(val, lane_base + PHY_RX_REG_B); + + /* Set init done */ + val = readl(lane_base + PCIE_PU_ADDR_CLK_CFG); + val = u32_replace_bits(val, 1, CFG_SW_PHY_INIT_DONE); + writel(val, lane_base + PCIE_PU_ADDR_CLK_CFG); + } + + ret = readl_poll_timeout(phy_base + PCIE_PU_ADDR_CLK_CFG, val, + (val & PHY_CLK_PLL_READY), PCIE_POLL_DELAY, + PCIE_PLL_TIMEOUT); + if (ret) { + dev_err(&lg->phy->dev, "PHY PLL lock timeout\n"); + return ret; + } + + return 0; +} + +const struct phy_ops k3_pcie_phy_ops = { + .init = k3_pcie_phy_init, + .owner = THIS_MODULE, +}; +EXPORT_SYMBOL_GPL(k3_pcie_phy_ops); + +/* PHY rcal init requires APB_SPARE regmap access */ + +#define APB_SPARE_PU_CAL 0x178 +#define PU_CAL BIT(17) + +#define APB_SPARE_RCAL_HSIO 0x17c +#define APB_SPARE_PU_CAL_DONE BIT(8) +#define RCAL_OVRD_PTRIM GENMASK(23, 20) +#define RCAL_OVRD_NTRIM GENMASK(27, 24) +#define RCAL_OVRD_PTRIM_EN BIT(28) +#define RCAL_OVRD_NTRIM_EN BIT(29) +#define RCAL_OVRD_STABLE_VAL BIT(30) +#define RCAL_OVRD_STABLE_EN BIT(31) + +#define RCAL_OVRD_TRIM_EN (RCAL_OVRD_NTRIM_EN | RCAL_OVRD_PTRIM_EN) +#define RCAL_OVRD_TRIM_MASK (RCAL_OVRD_NTRIM | RCAL_OVRD_PTRIM) + +#define PU_CAL_TIMEOUT 2000000 + +static DEFINE_MUTEX(calibrate_lock); + +int k3_phy_calibrate(struct regmap *apb_spare) +{ + unsigned int val = 0; + int ret; + + guard(mutex)(&calibrate_lock); + + regmap_read(apb_spare, APB_SPARE_RCAL_HSIO, &val); + if (val & APB_SPARE_PU_CAL_DONE) + return 0; + + regmap_update_bits(apb_spare, APB_SPARE_PU_CAL, PU_CAL, + PU_CAL); + + ret = regmap_read_poll_timeout(apb_spare, APB_SPARE_RCAL_HSIO, + val, (val & APB_SPARE_PU_CAL_DONE), PCIE_POLL_DELAY, + PU_CAL_TIMEOUT); + + if (ret) + regmap_update_bits(apb_spare, APB_SPARE_RCAL_HSIO, + RCAL_OVRD_TRIM_EN | RCAL_OVRD_STABLE_VAL | + RCAL_OVRD_TRIM_MASK | RCAL_OVRD_STABLE_EN, + RCAL_OVRD_TRIM_EN | RCAL_OVRD_STABLE_VAL | + FIELD_PREP(RCAL_OVRD_NTRIM, 0x6) | + FIELD_PREP(RCAL_OVRD_PTRIM, 0xa) | + RCAL_OVRD_STABLE_EN); + + return 0; +} +EXPORT_SYMBOL_GPL(k3_phy_calibrate); + +MODULE_DESCRIPTION("SpacemiT K3 PHY common ops"); +MODULE_LICENSE("GPL"); diff --git a/drivers/phy/spacemit/phy-k3-common.h b/drivers/phy/spacemit/phy-k3-common.h new file mode 100644 index 000000000000..49009c3c313a --- /dev/null +++ b/drivers/phy/spacemit/phy-k3-common.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _PHY_K3_COMMON_H +#define _PHY_K3_COMMON_H + +#include + +struct k3_phy_lane_group_data { + u32 lanes; + u8 config; + u8 mask; + u32 offsets[] __counted_by(lanes); +}; + +struct k3_lane_group { + const struct k3_phy_lane_group_data *data; + void __iomem *base; + struct phy *phy; + bool is_pcie; +}; + +extern const struct phy_ops k3_pcie_phy_ops; +extern const struct phy_ops k3_usb3_phy_ops; + +int k3_phy_calibrate(struct regmap *apb_spare); + +#endif -- cgit v1.2.3 From 2ec9c210c1f931389709aee403d28e4f32676385 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Mon, 13 Jul 2026 12:38:05 +0200 Subject: phy: mediatek: Add support for MT8196 MIPI DSI PHY Add support for the MIPI DSI PHY found in the MediaTek MT8196 SoC and its variants. This PHY has a different register layout and provides support for more hardware features compared to the previous generation. This initial driver only adds support for basic functionality that is necessary to drive MIPI DSI displays as a D-PHY. Feature additions like lane-swap, DPHY/CPHY switching, dual-port, and others, may be done in the future. Signed-off-by: AngeloGioacchino Del Regno Link: https://patch.msgid.link/20260713103805.23030-3-angelogioacchino.delregno@collabora.com Signed-off-by: Vinod Koul --- drivers/phy/mediatek/Makefile | 1 + drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8196.c | 201 +++++++++++++++++++++++++ drivers/phy/mediatek/phy-mtk-mipi-dsi.c | 1 + drivers/phy/mediatek/phy-mtk-mipi-dsi.h | 2 +- 4 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8196.c (limited to 'drivers') diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile index 1b8088df71e8..ed0da708759b 100644 --- a/drivers/phy/mediatek/Makefile +++ b/drivers/phy/mediatek/Makefile @@ -21,4 +21,5 @@ obj-$(CONFIG_PHY_MTK_MIPI_CSI_0_5) += phy-mtk-mipi-csi-0-5.o phy-mtk-mipi-dsi-drv-y := phy-mtk-mipi-dsi.o phy-mtk-mipi-dsi-drv-y += phy-mtk-mipi-dsi-mt8173.o phy-mtk-mipi-dsi-drv-y += phy-mtk-mipi-dsi-mt8183.o +phy-mtk-mipi-dsi-drv-y += phy-mtk-mipi-dsi-mt8196.o obj-$(CONFIG_PHY_MTK_MIPI_DSI) += phy-mtk-mipi-dsi-drv.o diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8196.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8196.c new file mode 100644 index 000000000000..eac3db9922db --- /dev/null +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8196.c @@ -0,0 +1,201 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: jitao.shi + * + * Copyright (c) 2026 Collabora Ltd. + * AngeloGioacchino Del Regno + */ + +#include "phy-mtk-io.h" +#include "phy-mtk-mipi-dsi.h" + +#define MIPITX_LANE_CON 0x0004 +#define RG_DSI_CPHY_T1DRV_EN BIT(0) +#define RG_DSI_ANA_CK_SEL BIT(1) +#define RG_DSI_PHY_CK_SEL BIT(2) +#define RG_DSI_CPHY_EN BIT(3) +#define RG_DSI_PHYCK_INV_EN BIT(4) +#define RG_DSI_PWR04_EN BIT(5) +#define RG_DSI_BG_LPF_EN BIT(6) +#define RG_DSI_BG_CORE_EN BIT(7) +#define RG_DSI_PAD_TIEL_SEL BIT(8) + +#define MIPITX_VOLTAGE_SEL 0x0008 +#define RG_DSI_HSTX_LDO_REF_SEL GENMASK(9, 6) +#define RG_DSI_PRD_REF_SEL GENMASK(5, 0) +#define RG_DSI_PRD_REF_MINI 0 +#define RG_DSI_PRD_REF_DEF 4 +#define RG_DSI_PRD_REF_MAX 7 + +#define MIPITX_PRESERVED 0x000c +#define MIPITX_PRESERVED_DEF 0xffff0040 +#define MIPITX_PRESERVED_MINI 0xffff00f0 + +#define MIPITX_PLL_PWR 0x0028 +#define AD_DSI_PLL_SDM_PWR_ON BIT(0) +#define AD_DSI_PLL_SDM_ISO_EN BIT(1) +#define MIPITX_PLL_CON0 0x002c +#define MIPITX_PLL_CON1 0x0030 +#define RG_DSI_PLL_EN BIT(0) +#define RG_DSI_PLL_POSDIV GENMASK(10, 8) +#define MIPITX_PLL_CON2 0x0034 +#define MIPITX_PLL_CON3 0x0038 +#define MIPITX_PLL_CON4 0x003c +#define RG_DSI_PLL_IBIAS GENMASK(11, 10) + +#define MIPITX_D2_SW_CTL_EN 0x015c +#define MIPITX_D0_SW_CTL_EN 0x025c +#define MIPITX_CK_CKMODE_EN 0x0320 +#define DSI_CK_CKMODE_EN BIT(0) +#define MIPITX_CK_SW_CTL_EN 0x035c +#define MIPITX_D1_SW_CTL_EN 0x045c +#define MIPITX_D3_SW_CTL_EN 0x055c +#define DSI_SW_CTL_EN BIT(0) + +#define DSI_PHY_XTAL_CLK_HZ 26000000 +#define DSI_PHY_PLL_MIN_RATE_HZ 125000000 +#define DSI_PHY_PLL_MAX_RATE_HZ 2000000000 + +static int mtk_mipi_tx_pll_enable(struct clk_hw *hw) +{ + struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); + void __iomem *base = mipi_tx->regs; + u32 voltage = RG_DSI_PRD_REF_MINI; + u32 pres = MIPITX_PRESERVED_MINI; + unsigned long long pcw_calc; + unsigned int txdiv, txdiv0; + u32 pcw; + + dev_dbg(mipi_tx->dev, "enable: %u bps\n", mipi_tx->data_rate); + + if (mipi_tx->data_rate >= DSI_PHY_PLL_MAX_RATE_HZ) { + /* Select higher signaling voltage for fast data rates */ + voltage = RG_DSI_PRD_REF_DEF; + pres = MIPITX_PRESERVED_DEF; + txdiv = 1; + txdiv0 = 0; + } else if (mipi_tx->data_rate >= 1000000000) { + txdiv = 2; + txdiv0 = 1; + } else if (mipi_tx->data_rate >= 500000000) { + txdiv = 4; + txdiv0 = 2; + } else if (mipi_tx->data_rate > 250000000) { + txdiv = 8; + txdiv0 = 3; + } else if (mipi_tx->data_rate >= 125000000) { + txdiv = 16; + txdiv0 = 4; + } else { + return -EINVAL; + } + + pcw_calc = ((u64)(mipi_tx->data_rate / 2) * txdiv) << 24; + pcw_calc = div_u64(pcw_calc, DSI_PHY_XTAL_CLK_HZ); + + if (pcw_calc > U32_MAX) { + dev_err(mipi_tx->dev, "Calculated PCW=%llu overflow!\n", pcw_calc); + return -EINVAL; + } + pcw = (u32)pcw_calc; + + mtk_phy_update_field(base + MIPITX_VOLTAGE_SEL, RG_DSI_PRD_REF_SEL, voltage); + writel(pres, base + MIPITX_PRESERVED); + + /* Enable the SDM and wait for power to stabilize */ + mtk_phy_set_bits(base + MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON); + mtk_phy_clear_bits(base + MIPITX_PLL_CON1, RG_DSI_PLL_EN); + udelay(30); + + /* Disable isolation and program PLL's PCW and dividers */ + mtk_phy_clear_bits(base + MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN); + writel(pcw, base + MIPITX_PLL_CON0); + mtk_phy_update_field(base + MIPITX_PLL_CON1, RG_DSI_PLL_POSDIV, txdiv0); + + /* Enable the PLL and wait for the clock output to stabilize */ + mtk_phy_set_bits(base + MIPITX_PLL_CON1, RG_DSI_PLL_EN); + udelay(30); + + return 0; +} + +static void mtk_mipi_tx_pll_disable(struct clk_hw *hw) +{ + struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); + void __iomem *base = mipi_tx->regs; + + mtk_phy_clear_bits(base + MIPITX_PLL_CON1, RG_DSI_PLL_EN); + + mtk_phy_set_bits(base + MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN); + mtk_phy_clear_bits(base + MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON); +} + +static int mtk_mipi_tx_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + req->rate = clamp_val(req->rate, + DSI_PHY_PLL_MIN_RATE_HZ, DSI_PHY_PLL_MAX_RATE_HZ); + + return 0; +} + +static const struct clk_ops mtk_mipi_tx_pll_ops = { + .enable = mtk_mipi_tx_pll_enable, + .disable = mtk_mipi_tx_pll_disable, + .determine_rate = mtk_mipi_tx_pll_determine_rate, + .set_rate = mtk_mipi_tx_pll_set_rate, + .recalc_rate = mtk_mipi_tx_pll_recalc_rate, +}; + +static void mtk_mipi_tx_power_on_signal(struct phy *phy) +{ + struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy); + void __iomem *base = mipi_tx->regs; + + /* BG_LPF_EN / BG_CORE_EN */ + writel(RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN, base + MIPITX_LANE_CON); + /* Wait for MIPI core to enable */ + usleep_range(30, 100); + writel(RG_DSI_BG_CORE_EN | RG_DSI_BG_LPF_EN, base + MIPITX_LANE_CON); + + /* Switch OFF each Lane */ + mtk_phy_clear_bits(base + MIPITX_D0_SW_CTL_EN, DSI_SW_CTL_EN); + mtk_phy_clear_bits(base + MIPITX_D1_SW_CTL_EN, DSI_SW_CTL_EN); + mtk_phy_clear_bits(base + MIPITX_D2_SW_CTL_EN, DSI_SW_CTL_EN); + mtk_phy_clear_bits(base + MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN); + mtk_phy_clear_bits(base + MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN); + + /* + * The MIPI TX drive strength is in the range of 3000 ~ 6000 microamps: + * RG_DSI_HSTX_LDO_REF_SEL expresses an offset from the minimum drive + * strength (3000uA) and can add a maximum offset of 3000uA, reaching a + * maximum drive strength of 3000+3000=6000uA. + */ + mtk_phy_update_field(base + MIPITX_VOLTAGE_SEL, RG_DSI_HSTX_LDO_REF_SEL, + (mipi_tx->mipitx_drive - 3000) / 200); + + mtk_phy_set_bits(base + MIPITX_CK_CKMODE_EN, DSI_CK_CKMODE_EN); +} + +static void mtk_mipi_tx_power_off_signal(struct phy *phy) +{ + struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy); + void __iomem *base = mipi_tx->regs; + + /* Switch ON each lane one by one */ + mtk_phy_set_bits(base + MIPITX_D0_SW_CTL_EN, DSI_SW_CTL_EN); + mtk_phy_set_bits(base + MIPITX_D1_SW_CTL_EN, DSI_SW_CTL_EN); + mtk_phy_set_bits(base + MIPITX_D2_SW_CTL_EN, DSI_SW_CTL_EN); + mtk_phy_set_bits(base + MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN); + mtk_phy_set_bits(base + MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN); + + writel(RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN, base + MIPITX_LANE_CON); + writel(RG_DSI_PAD_TIEL_SEL, base + MIPITX_LANE_CON); +} + +const struct mtk_mipitx_data mt8196_mipitx_data = { + .mipi_tx_clk_ops = &mtk_mipi_tx_pll_ops, + .mipi_tx_enable_signal = mtk_mipi_tx_power_on_signal, + .mipi_tx_disable_signal = mtk_mipi_tx_power_off_signal, +}; diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c index 065ea626093a..46f0cb3ac096 100644 --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c @@ -183,6 +183,7 @@ static const struct of_device_id mtk_mipi_tx_match[] = { { .compatible = "mediatek,mt2701-mipi-tx", .data = &mt2701_mipitx_data }, { .compatible = "mediatek,mt8173-mipi-tx", .data = &mt8173_mipitx_data }, { .compatible = "mediatek,mt8183-mipi-tx", .data = &mt8183_mipitx_data }, + { .compatible = "mediatek,mt8196-mipi-tx", .data = &mt8196_mipitx_data }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, mtk_mipi_tx_match); diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.h b/drivers/phy/mediatek/phy-mtk-mipi-dsi.h index 5d4876f1dc95..e6f967078e3b 100644 --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.h +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.h @@ -42,5 +42,5 @@ unsigned long mtk_mipi_tx_pll_recalc_rate(struct clk_hw *hw, extern const struct mtk_mipitx_data mt2701_mipitx_data; extern const struct mtk_mipitx_data mt8173_mipitx_data; extern const struct mtk_mipitx_data mt8183_mipitx_data; - +extern const struct mtk_mipitx_data mt8196_mipitx_data; #endif -- cgit v1.2.3 From 910b828b22b7b91054b3bd4be676a017444b0e00 Mon Sep 17 00:00:00 2001 From: Krishna Chaitanya Chundru Date: Thu, 9 Jul 2026 12:05:16 +0530 Subject: phy: qcom: qmp-pcie: Skip PHY reset if already up If the bootloader has already powered up the PCIe PHY, performing a full reset and waiting for the PHY to come up again adds unnecessary delay during boot. Extend the existing skip_init handling by introducing a skip_reset condition. When skip_init is active and the PHY status indicates that the PHY is already operational, skip asserting and deasserting the no-csr reset while still enabling the required resources during power-on. This allows reusing the bootloader-initialized PHY state and avoids redundant PHY reinitialization and PCIe link retraining, which can add hundred's of milliseconds of delay. This relies on the assumption that when skip_init is enabled and the PHY is reported as up, the bootloader has already configured the PHY correctly and the link is in a usable state. Reviewed-by: Abel Vesa Reviewed-by: Konrad Dybcio Tested-by: Qiang Yu Signed-off-by: Krishna Chaitanya Chundru Link: https://patch.msgid.link/20260709-link_retain-v3-1-81a9d187bb61@oss.qualcomm.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c index 357a2e2f8ff6..f54f66429f37 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c @@ -5231,6 +5231,7 @@ static int qmp_pcie_init(struct phy *phy) struct qmp_pcie *qmp = phy_get_drvdata(phy); const struct qmp_phy_cfg *cfg = qmp->cfg; void __iomem *pcs = qmp->pcs; + bool skip_reset; int ret; /* @@ -5246,6 +5247,9 @@ static int qmp_pcie_init(struct phy *phy) qphy_checkbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START | PCS_START) && qphy_checkbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], cfg->pwrdn_ctrl); + skip_reset = qmp->skip_init && !qphy_checkbits(pcs, cfg->regs[QPHY_PCS_STATUS], + cfg->phy_status); + if (!qmp->skip_init && !cfg->tbls.serdes_num) { dev_err(qmp->dev, "Init sequence not available\n"); return -ENODATA; @@ -5269,13 +5273,15 @@ static int qmp_pcie_init(struct phy *phy) } } - ret = reset_control_assert(qmp->nocsr_reset); - if (ret) { - dev_err(qmp->dev, "no-csr reset assert failed\n"); - goto err_assert_reset; - } + if (!skip_reset) { + ret = reset_control_assert(qmp->nocsr_reset); + if (ret) { + dev_err(qmp->dev, "no-csr reset assert failed\n"); + goto err_assert_reset; + } - usleep_range(200, 300); + usleep_range(200, 300); + } if (!qmp->skip_init) { ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets); @@ -5325,8 +5331,11 @@ static int qmp_pcie_power_on(struct phy *phy) void __iomem *pcs = qmp->pcs; void __iomem *status; unsigned int mask, val; + bool skip_reset; int ret; + skip_reset = qmp->skip_init && !qphy_checkbits(pcs, cfg->regs[QPHY_PCS_STATUS], + cfg->phy_status); /* * Write CSR register for PHY that doesn't support no_csr reset or has not * been initialized. @@ -5350,10 +5359,12 @@ skip_tbls_init: if (ret) return ret; - ret = reset_control_deassert(qmp->nocsr_reset); - if (ret) { - dev_err(qmp->dev, "no-csr reset deassert failed\n"); - goto err_disable_pipe_clk; + if (!skip_reset) { + ret = reset_control_deassert(qmp->nocsr_reset); + if (ret) { + dev_err(qmp->dev, "no-csr reset deassert failed\n"); + goto err_disable_pipe_clk; + } } if (qmp->skip_init) -- cgit v1.2.3 From 1e0c8d50663ae2afd2307d617fd94a53f6a1dc02 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Fri, 12 Jun 2026 15:57:31 +0300 Subject: phy: lynx-10g: fix lynx_10g_pccr_val_enabled() The intention of the code is to extract the PCCR8_SGMIIa_CFG field out of the "pccr" value, not to create a new value with the PCCR8_SGMIIa_CFG field set to the "pccr" value. Since FIELD_GET() is implemented as ((reg) & (mask)) >> __bf_shf(mask) and FIELD_PREP() as (val) << __bf_shf(mask)) & (mask) and since "mask" is GENMASK(2, 0), in practice there is no functional difference between FIELD_GET() and FIELD_PREP(). But FIELD_GET() is logically the correct helper. Signed-off-by: Vladimir Oltean Link: https://patch.msgid.link/20260612125731.133330-1-vladimir.oltean@nxp.com Signed-off-by: Vinod Koul --- drivers/phy/freescale/phy-fsl-lynx-10g.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/phy/freescale/phy-fsl-lynx-10g.c b/drivers/phy/freescale/phy-fsl-lynx-10g.c index 38def160ef1a..1362d1ebb3d4 100644 --- a/drivers/phy/freescale/phy-fsl-lynx-10g.c +++ b/drivers/phy/freescale/phy-fsl-lynx-10g.c @@ -386,7 +386,7 @@ static void lynx_10g_backup_pccr_val(struct lynx_lane *lane) */ static bool lynx_10g_pccr_val_enabled(u32 pccr) { - return FIELD_PREP(PCCR8_SGMIIa_CFG, pccr) != 0; + return FIELD_GET(PCCR8_SGMIIa_CFG, pccr) != 0; } static bool lynx_10g_lane_is_3_125g(struct lynx_lane *lane) -- cgit v1.2.3 From 346121aed2866a62c57395689f021f97a532a749 Mon Sep 17 00:00:00 2001 From: Krishna Kurapati Date: Sun, 12 Jul 2026 20:58:36 +0530 Subject: phy: qcom-qusb2: Add support for Shikra Add init sequence and phy configuration for Shikra. Since the init sequence is same as that of QCS615, reuse the existing init table in Shikra. Signed-off-by: Krishna Kurapati Reviewed-by: Dmitry Baryshkov Link: https://patch.msgid.link/20260712-usb-shikra-phy-v6-v6-3-1b3e51bf1541@oss.qualcomm.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-qusb2.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c index eb93015be841..2e5fdb620cb2 100644 --- a/drivers/phy/qualcomm/phy-qcom-qusb2.c +++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c @@ -381,6 +381,17 @@ static const struct qusb2_phy_cfg sdm660_phy_cfg = { .autoresume_en = BIT(3), }; +static const struct qusb2_phy_cfg shikra_phy_cfg = { + .tbl = qcs615_init_tbl, + .tbl_num = ARRAY_SIZE(qcs615_init_tbl), + .regs = msm8996_regs_layout, + + .has_pll_test = true, + .se_clk_scheme_default = true, + .disable_ctrl = CLAMP_N_EN | FREEZIO_N | POWER_DOWN, + .mask_core_ready = PLL_LOCKED, +}; + static const struct qusb2_phy_cfg sm6115_phy_cfg = { .tbl = sm6115_init_tbl, .tbl_num = ARRAY_SIZE(sm6115_init_tbl), @@ -958,6 +969,9 @@ static const struct of_device_id qusb2_phy_of_match_table[] = { }, { .compatible = "qcom,sdm660-qusb2-phy", .data = &sdm660_phy_cfg, + }, { + .compatible = "qcom,shikra-qusb2-phy", + .data = &shikra_phy_cfg, }, { .compatible = "qcom,sm4250-qusb2-phy", .data = &sm6115_phy_cfg, -- cgit v1.2.3 From edb7772bb3b5ebd5e8efacfaabaade643fc4b77b Mon Sep 17 00:00:00 2001 From: Krishna Kurapati Date: Sun, 12 Jul 2026 20:58:37 +0530 Subject: phy: qcom: qmp-usbc: Add qmp configuration for Shikra Add init sequence and phy configuration for the Super Speed port on Shikra SoC. Also since Shikra uses 3 resets, add support for the third reset and configure Shikra platform data to use 3 resets. Signed-off-by: Krishna Kurapati Reviewed-by: Dmitry Baryshkov Link: https://patch.msgid.link/20260712-usb-shikra-phy-v6-v6-4-1b3e51bf1541@oss.qualcomm.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 53 ++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c index ab3055bb5b0c..fa8492b487d7 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c @@ -512,10 +512,14 @@ static const char * const usb3phy_reset_l[] = { "phy_phy", "phy", }; -static const char * const usb3dpphy_reset_l[] = { +static const char * const qcs615_usb3dpphy_reset_l[] = { "phy_phy", "dp_phy", }; +static const char * const shikra_usb3dpphy_reset_l[] = { + "phy_phy", "dp_phy", "phy", +}; + static const struct regulator_bulk_data qmp_phy_msm8998_vreg_l[] = { { .supply = "vdda-phy", .init_load_uA = 68600 }, { .supply = "vdda-pll", .init_load_uA = 14200 }, @@ -680,8 +684,48 @@ static const struct qmp_phy_cfg qcs615_usb3dp_phy_cfg = { .configure_dp_phy = qcs615_qmp_configure_dp_phy, .calibrate_dp_phy = qcs615_qmp_calibrate_dp_phy, - .reset_list = usb3dpphy_reset_l, - .num_resets = ARRAY_SIZE(usb3dpphy_reset_l), + .reset_list = qcs615_usb3dpphy_reset_l, + .num_resets = ARRAY_SIZE(qcs615_usb3dpphy_reset_l), + .vreg_list = qmp_phy_qcs615_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_qcs615_vreg_l), +}; + +static const struct qmp_phy_cfg shikra_usb3dp_phy_cfg = { + .offsets = &qmp_usbc_usb3dp_offsets_qcs615, + + .serdes_tbl = qcm2290_usb3_serdes_tbl, + .serdes_tbl_num = ARRAY_SIZE(qcm2290_usb3_serdes_tbl), + .tx_tbl = qcm2290_usb3_tx_tbl, + .tx_tbl_num = ARRAY_SIZE(qcm2290_usb3_tx_tbl), + .rx_tbl = qcm2290_usb3_rx_tbl, + .rx_tbl_num = ARRAY_SIZE(qcm2290_usb3_rx_tbl), + .pcs_tbl = qcm2290_usb3_pcs_tbl, + .pcs_tbl_num = ARRAY_SIZE(qcm2290_usb3_pcs_tbl), + + .regs = qmp_v3_usb3phy_regs_layout_qcm2290, + + .dp_serdes_tbl = qcs615_dp_serdes_tbl, + .dp_serdes_tbl_num = ARRAY_SIZE(qcs615_dp_serdes_tbl), + .dp_tx_tbl = qcs615_dp_tx_tbl, + .dp_tx_tbl_num = ARRAY_SIZE(qcs615_dp_tx_tbl), + + .serdes_tbl_rbr = qcs615_dp_serdes_tbl_rbr, + .serdes_tbl_rbr_num = ARRAY_SIZE(qcs615_dp_serdes_tbl_rbr), + .serdes_tbl_hbr = qcs615_dp_serdes_tbl_hbr, + .serdes_tbl_hbr_num = ARRAY_SIZE(qcs615_dp_serdes_tbl_hbr), + .serdes_tbl_hbr2 = qcs615_dp_serdes_tbl_hbr2, + .serdes_tbl_hbr2_num = ARRAY_SIZE(qcs615_dp_serdes_tbl_hbr2), + + .swing_tbl = &qcs615_dp_voltage_swing_hbr2_rbr, + .pre_emphasis_tbl = &qcs615_dp_pre_emphasis_hbr2_rbr, + + .dp_aux_init = qcs615_qmp_dp_aux_init, + .configure_dp_tx = qcs615_qmp_configure_dp_tx, + .configure_dp_phy = qcs615_qmp_configure_dp_phy, + .calibrate_dp_phy = qcs615_qmp_calibrate_dp_phy, + + .reset_list = shikra_usb3dpphy_reset_l, + .num_resets = ARRAY_SIZE(shikra_usb3dpphy_reset_l), .vreg_list = qmp_phy_qcs615_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_qcs615_vreg_l), }; @@ -2019,6 +2063,9 @@ static const struct of_device_id qmp_usbc_of_match_table[] = { }, { .compatible = "qcom,sdm660-qmp-usb3-phy", .data = &sdm660_usb3phy_cfg, + }, { + .compatible = "qcom,shikra-qmp-usb3-dp-phy", + .data = &shikra_usb3dp_phy_cfg, }, { .compatible = "qcom,sm6115-qmp-usb3-phy", .data = &qcm2290_usb3phy_cfg, -- cgit v1.2.3 From 3c25d3d97428a88f451590aeca9e6da3c12e495d Mon Sep 17 00:00:00 2001 From: Varadarajan Narayanan Date: Tue, 21 Jul 2026 13:05:27 +0530 Subject: phy: qcom-qmp-pcie: Add support for ipq5210 PCIe phys Add support for a PCIe phys found on Qualcomm ipq5210 platform. Reviewed-by: Dmitry Baryshkov Signed-off-by: Varadarajan Narayanan Link: https://patch.msgid.link/20260721-pcie-phy-v5-2-8d403ef7e780@oss.qualcomm.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 129 +++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) (limited to 'drivers') diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c index f54f66429f37..f4b25a7b1604 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c @@ -636,6 +636,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), @@ -4061,6 +4144,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, @@ -5929,6 +6055,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = { }, { .compatible = "qcom,hawi-qmp-gen4x1-pcie-phy", .data = &hawi_qmp_gen4x1_pciephy_cfg, + }, { + .compatible = "qcom,ipq5210-qmp-gen3x1-pcie-phy", + .data = &ipq5210_gen3x1_pciephy_cfg, }, { .compatible = "qcom,ipq6018-qmp-pcie-phy", .data = &ipq6018_pciephy_cfg, -- cgit v1.2.3 From ee6aa0f01d4e8eddf1c7fda49d65c7ef12444e78 Mon Sep 17 00:00:00 2001 From: Kathiravan Thirumoorthy Date: Fri, 10 Jul 2026 23:16:41 +0530 Subject: phy: qcom: qmp-pcie: Add IPQ9650 PCIe PHY support Add support for the IPQ9650 platform, which includes three Gen3 x2 PCIe controllers and two Gen3 x1 PCIe controllers. The PHY instances require the on-chip refgen supply. Add the IPQ9650 Gen3 x1 and x2 QMP PCIe PHY configurations along with the refgen regulator supply. Note that an on-chip LDO, driven by the SoC CX, supplies the PHY voltages without requiring software control. Note that IPQ9650 does not support CX power collapse or rail scaling. Reviewed-by: Dmitry Baryshkov Signed-off-by: Kathiravan Thirumoorthy Link: https://patch.msgid.link/20260710-ipq9650_pcie_phy-v3-2-ef6018818d33@oss.qualcomm.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 220 +++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) (limited to 'drivers') diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c index f4b25a7b1604..27034bb62d0d 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c @@ -956,6 +956,152 @@ static const struct qmp_phy_init_tbl ipq9574_gen3x2_pcie_pcs_misc_tbl[] = { QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1), }; +static const struct qmp_phy_init_tbl ipq9650_pcie_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CTRL_BY_PSM, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MODE, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_CONFIG, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x42), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_RESETSM_CNTRL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_TIMER1, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_TIMER2, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x68), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0, 0xab), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xd4), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE0, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0, 0x24), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SVS_MODE_CLK_SEL, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYS_CLK_CTRL, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BG_TIMER, 0x0b), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x90), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x53), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x29), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE1, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1, 0xb4), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SVS_MODE_CLK_SEL, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORE_CLK_EN, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x7d), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xa2), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x13), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xb5), +}; + +static const struct qmp_phy_init_tbl ipq9650_pcie_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2, 0x12), + QMP_PHY_INIT_CFG(QSERDES_V4_TX_HIGHZ_DRVR_EN, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0xb5), + QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL, 0x00), +}; + +static const struct qmp_phy_init_tbl ipq9650_pcie_rx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x11), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_ENABLES, 0x1c), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_VGA_GAIN2_LSB, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_VGA_GAIN2_MSB, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_TX_ADAPT_PRE_THRESH1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_TX_ADAPT_PRE_THRESH2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_TX_ADAPT_POST_THRESH, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_TX_ADAPT_MAIN_THRESH, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04), + 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_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xd4), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0x54), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xdb), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0x31), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x24), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xe4), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xec), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x67), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3a), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0), +}; + +static const struct qmp_phy_init_tbl ipq9650_pcie_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x25), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_G12S1_TXDEEMPH_M3P5DB, 0x10), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_RATE_SLEW_CNTRL1, 0x03), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG2, 0x0f), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_DCC_CAL_CONFIG, 0x00), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0x77), +}; + +static const struct qmp_phy_init_tbl ipq9650_pcie_pcs_misc_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG2, 0x0d), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG4, 0x07), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1), + 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_INT_AUX_CLK_CONFIG1, 0x00), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG1, 0x1c), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG2, 0x0b), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P2_P3_POST, 0x34), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P6_P7_PRE, 0x33), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P6_P7_POST, 0x40), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_PRE, 0x00), + QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_POST, 0x58), +}; + static const struct qmp_phy_init_tbl qcs615_pcie_serdes_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_V2_COM_BIAS_EN_CLKBUFLR_EN, 0x18), QMP_PHY_INIT_CFG(QSERDES_V2_COM_CLK_ENABLE1, 0x10), @@ -3864,6 +4010,10 @@ static const char * const qmp_phy_vreg_l[] = { "vdda-phy", "vdda-pll", }; +static const char * const ipq9650_qmp_phy_vreg_l[] = { + "refgen", +}; + static const char * const sm8550_qmp_phy_vreg_l[] = { "vdda-phy", "vdda-pll", "vdda-qref", }; @@ -3907,6 +4057,14 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v4x1 = { .rx = 0x0400, }; +static const struct qmp_pcie_offsets qmp_pcie_offsets_9650_v4x1 = { + .serdes = 0, + .pcs = 0x0600, + .pcs_misc = 0x0a00, + .tx = 0x0200, + .rx = 0x0400, +}; + static const struct qmp_pcie_offsets qmp_pcie_offsets_v4x2 = { .serdes = 0, .pcs = 0x0a00, @@ -4243,6 +4401,62 @@ static const struct qmp_phy_cfg ipq9574_gen3x2_pciephy_cfg = { .pipe_clock_rate = 250000000, }; +static const struct qmp_phy_cfg ipq9650_gen3x1_pciephy_cfg = { + .lanes = 1, + + .offsets = &qmp_pcie_offsets_9650_v4x1, + + .tbls = { + .serdes = ipq9650_pcie_serdes_tbl, + .serdes_num = ARRAY_SIZE(ipq9650_pcie_serdes_tbl), + .tx = ipq9650_pcie_tx_tbl, + .tx_num = ARRAY_SIZE(ipq9650_pcie_tx_tbl), + .rx = ipq9650_pcie_rx_tbl, + .rx_num = ARRAY_SIZE(ipq9650_pcie_rx_tbl), + .pcs = ipq9650_pcie_pcs_tbl, + .pcs_num = ARRAY_SIZE(ipq9650_pcie_pcs_tbl), + .pcs_misc = ipq9650_pcie_pcs_misc_tbl, + .pcs_misc_num = ARRAY_SIZE(ipq9650_pcie_pcs_misc_tbl), + }, + .reset_list = ipq8074_pciephy_reset_l, + .num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l), + .vreg_list = ipq9650_qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(ipq9650_qmp_phy_vreg_l), + .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 ipq9650_gen3x2_pciephy_cfg = { + .lanes = 2, + + .offsets = &qmp_pcie_offsets_v4x2, + + .tbls = { + .serdes = ipq9650_pcie_serdes_tbl, + .serdes_num = ARRAY_SIZE(ipq9650_pcie_serdes_tbl), + .tx = ipq9650_pcie_tx_tbl, + .tx_num = ARRAY_SIZE(ipq9650_pcie_tx_tbl), + .rx = ipq9650_pcie_rx_tbl, + .rx_num = ARRAY_SIZE(ipq9650_pcie_rx_tbl), + .pcs = ipq9650_pcie_pcs_tbl, + .pcs_num = ARRAY_SIZE(ipq9650_pcie_pcs_tbl), + .pcs_misc = ipq9650_pcie_pcs_misc_tbl, + .pcs_misc_num = ARRAY_SIZE(ipq9650_pcie_pcs_misc_tbl), + }, + .reset_list = ipq8074_pciephy_reset_l, + .num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l), + .vreg_list = ipq9650_qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(ipq9650_qmp_phy_vreg_l), + .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 qcs615_pciephy_cfg = { .lanes = 1, @@ -6073,6 +6287,12 @@ static const struct of_device_id qmp_pcie_of_match_table[] = { }, { .compatible = "qcom,ipq9574-qmp-gen3x2-pcie-phy", .data = &ipq9574_gen3x2_pciephy_cfg, + }, { + .compatible = "qcom,ipq9650-qmp-gen3x1-pcie-phy", + .data = &ipq9650_gen3x1_pciephy_cfg, + }, { + .compatible = "qcom,ipq9650-qmp-gen3x2-pcie-phy", + .data = &ipq9650_gen3x2_pciephy_cfg, }, { .compatible = "qcom,kaanapali-qmp-gen3x2-pcie-phy", .data = &qmp_v8_gen3x2_pciephy_cfg, -- cgit v1.2.3