phy: qcom-qmp-pcie: add support for sc8280xp
authorJohan Hovold <johan+linaro@kernel.org>
Sat, 5 Nov 2022 14:59:38 +0000 (15:59 +0100)
committerVinod Koul <vkoul@kernel.org>
Thu, 10 Nov 2022 07:04:55 +0000 (12:34 +0530)
Add support for the single and dual-lane PHYs found on SC8280XP.

Note that the SC8280XP binding does not try to describe every register
subregion and instead the driver holds the corresponding offsets.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Link: https://lore.kernel.org/r/20221105145939.20318-16-johan+linaro@kernel.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v5.h

index d671b05..f507a67 100644 (file)
@@ -834,6 +834,143 @@ static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_pcs_misc_tbl[] = {
        QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
 };
 
+static const struct qmp_phy_init_tbl sc8280xp_qmp_pcie_serdes_tbl[] = {
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_EN_CENTER, 0x00),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER1, 0x31),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER2, 0x01),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE0, 0xde),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE0, 0x07),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE1, 0x06),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_ENABLE1, 0x90),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x06),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x06),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x16),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x16),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x36),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x36),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0x08),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x42),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0x0a),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x1a),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x14),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x34),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x68),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE0, 0x55),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE0, 0x55),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE0, 0x03),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE1, 0xab),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE1, 0xaa),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE1, 0x02),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE1_MODE0, 0x24),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE1_MODE1, 0xb4),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE2_MODE1, 0x03),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_SELECT, 0x34),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x01),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE1, 0x08),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xb9),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x94),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x1_pcie_rc_serdes_tbl[] = {
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_BUF_ENABLE, 0x07),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x2_pcie_rc_serdes_tbl[] = {
+       QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x1_pcie_tx_tbl[] = {
+       QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x20),
+       QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0x75),
+       QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
+       QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x1d),
+       QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0c),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x1_pcie_rx_tbl[] = {
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x7f),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0xff),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xbf),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3f),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xd8),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xdc),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xdc),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0x5c),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x34),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa6),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_TX_ADAPT_POST_THRESH, 0xf0),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x34),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x07),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf0),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x1_pcie_pcs_tbl[] = {
+       QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x05),
+       QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0x77),
+       QMP_PHY_INIT_CFG(QPHY_V5_PCS_RATE_SLEW_CNTRL1, 0x0b),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x1_pcie_pcs_misc_tbl[] = {
+       QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
+       QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
+       QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_EQ_CONFIG2, 0x0f),
+       QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x2_pcie_tx_tbl[] = {
+       QMP_PHY_INIT_CFG_LANE(QSERDES_V5_TX_PI_QEC_CTRL, 0x02, 1),
+       QMP_PHY_INIT_CFG_LANE(QSERDES_V5_TX_PI_QEC_CTRL, 0x04, 2),
+       QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xd5),
+       QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
+       QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
+       QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0c),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x2_pcie_rx_tbl[] = {
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x7f),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0xff),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0x7f),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x34),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xd8),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xdc),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xdc),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0x5c),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x34),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa6),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x34),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf0),
+       QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x2_pcie_pcs_tbl[] = {
+       QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x05),
+       QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0x88),
+       QMP_PHY_INIT_CFG(QPHY_V5_PCS_RATE_SLEW_CNTRL1, 0x0b),
+       QMP_PHY_INIT_CFG(QPHY_V5_PCS_EQ_CONFIG3, 0x0f),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x2_pcie_pcs_misc_tbl[] = {
+       QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_POWER_STATE_CONFIG2, 0x1d),
+       QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
+       QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
+       QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
+};
+
 static const struct qmp_phy_init_tbl sm8250_qmp_pcie_serdes_tbl[] = {
        QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
        QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
@@ -1313,6 +1450,16 @@ static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_ep_pcs_misc_tbl[] =
        QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_OSC_DTCT_MODE2_CONFIG5, 0x08),
 };
 
+struct qmp_pcie_offsets {
+       u16 serdes;
+       u16 pcs;
+       u16 pcs_misc;
+       u16 tx;
+       u16 rx;
+       u16 tx2;
+       u16 rx2;
+};
+
 struct qmp_phy_cfg_tbls {
        const struct qmp_phy_init_tbl *serdes;
        int serdes_num;
@@ -1330,6 +1477,8 @@ struct qmp_phy_cfg_tbls {
 struct qmp_phy_cfg {
        int lanes;
 
+       const struct qmp_pcie_offsets *offsets;
+
        /* Main init sequence for PHY blocks - serdes, tx, rx, pcs */
        const struct qmp_phy_cfg_tbls tbls;
        /*
@@ -1422,6 +1571,9 @@ static const char * const msm8996_phy_clk_l[] = {
        "aux", "cfg_ahb", "ref",
 };
 
+static const char * const sc8280xp_pciephy_clk_l[] = {
+       "aux", "cfg_ahb", "ref", "rchng",
+};
 
 static const char * const sdm845_pciephy_clk_l[] = {
        "aux", "cfg_ahb", "ref", "refgen",
@@ -1441,6 +1593,16 @@ static const char * const sdm845_pciephy_reset_l[] = {
        "phy",
 };
 
+static const struct qmp_pcie_offsets qmp_pcie_offsets_v5 = {
+       .serdes         = 0,
+       .pcs            = 0x0200,
+       .pcs_misc       = 0x0600,
+       .tx             = 0x0e00,
+       .rx             = 0x1000,
+       .tx2            = 0x1600,
+       .rx2            = 0x1800,
+};
+
 static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
        .lanes                  = 1,
 
@@ -1700,6 +1862,76 @@ static const struct qmp_phy_cfg sc8180x_pciephy_cfg = {
        .phy_status             = PHYSTATUS,
 };
 
+static const struct qmp_phy_cfg sc8280xp_qmp_gen3x1_pciephy_cfg = {
+       .lanes                  = 1,
+
+       .offsets                = &qmp_pcie_offsets_v5,
+
+       .tbls = {
+               .serdes         = sc8280xp_qmp_pcie_serdes_tbl,
+               .serdes_num     = ARRAY_SIZE(sc8280xp_qmp_pcie_serdes_tbl),
+               .tx             = sc8280xp_qmp_gen3x1_pcie_tx_tbl,
+               .tx_num         = ARRAY_SIZE(sc8280xp_qmp_gen3x1_pcie_tx_tbl),
+               .rx             = sc8280xp_qmp_gen3x1_pcie_rx_tbl,
+               .rx_num         = ARRAY_SIZE(sc8280xp_qmp_gen3x1_pcie_rx_tbl),
+               .pcs            = sc8280xp_qmp_gen3x1_pcie_pcs_tbl,
+               .pcs_num        = ARRAY_SIZE(sc8280xp_qmp_gen3x1_pcie_pcs_tbl),
+               .pcs_misc       = sc8280xp_qmp_gen3x1_pcie_pcs_misc_tbl,
+               .pcs_misc_num   = ARRAY_SIZE(sc8280xp_qmp_gen3x1_pcie_pcs_misc_tbl),
+       },
+
+       .tbls_rc = &(const struct qmp_phy_cfg_tbls) {
+               .serdes         = sc8280xp_qmp_gen3x1_pcie_rc_serdes_tbl,
+               .serdes_num     = ARRAY_SIZE(sc8280xp_qmp_gen3x1_pcie_rc_serdes_tbl),
+       },
+
+       .clk_list               = sc8280xp_pciephy_clk_l,
+       .num_clks               = ARRAY_SIZE(sc8280xp_pciephy_clk_l),
+       .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                   = sm8250_pcie_regs_layout,
+
+       .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
+       .phy_status             = PHYSTATUS,
+};
+
+static const struct qmp_phy_cfg sc8280xp_qmp_gen3x2_pciephy_cfg = {
+       .lanes                  = 2,
+
+       .offsets                = &qmp_pcie_offsets_v5,
+
+       .tbls = {
+               .serdes         = sc8280xp_qmp_pcie_serdes_tbl,
+               .serdes_num     = ARRAY_SIZE(sc8280xp_qmp_pcie_serdes_tbl),
+               .tx             = sc8280xp_qmp_gen3x2_pcie_tx_tbl,
+               .tx_num         = ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_tx_tbl),
+               .rx             = sc8280xp_qmp_gen3x2_pcie_rx_tbl,
+               .rx_num         = ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_rx_tbl),
+               .pcs            = sc8280xp_qmp_gen3x2_pcie_pcs_tbl,
+               .pcs_num        = ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_pcs_tbl),
+               .pcs_misc       = sc8280xp_qmp_gen3x2_pcie_pcs_misc_tbl,
+               .pcs_misc_num   = ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_pcs_misc_tbl),
+       },
+
+       .tbls_rc = &(const struct qmp_phy_cfg_tbls) {
+               .serdes         = sc8280xp_qmp_gen3x2_pcie_rc_serdes_tbl,
+               .serdes_num     = ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_rc_serdes_tbl),
+       },
+
+       .clk_list               = sc8280xp_pciephy_clk_l,
+       .num_clks               = ARRAY_SIZE(sc8280xp_pciephy_clk_l),
+       .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                   = sm8250_pcie_regs_layout,
+
+       .pwrdn_ctrl             = SW_PWRDN | REFCLK_DRV_DSBL,
+       .phy_status             = PHYSTATUS,
+};
+
 static const struct qmp_phy_cfg sdx55_qmp_pciephy_cfg = {
        .lanes                  = 2,
 
@@ -2220,11 +2452,49 @@ static int qmp_pcie_parse_dt_legacy(struct qmp_pcie *qmp, struct device_node *np
        return 0;
 }
 
+static int qmp_pcie_parse_dt(struct qmp_pcie *qmp)
+{
+       struct platform_device *pdev = to_platform_device(qmp->dev);
+       const struct qmp_phy_cfg *cfg = qmp->cfg;
+       const struct qmp_pcie_offsets *offs = cfg->offsets;
+       struct device *dev = qmp->dev;
+       void __iomem *base;
+       int ret;
+
+       if (!offs)
+               return -EINVAL;
+
+       base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       qmp->serdes = base + offs->serdes;
+       qmp->pcs = base + offs->pcs;
+       qmp->pcs_misc = base + offs->pcs_misc;
+       qmp->tx = base + offs->tx;
+       qmp->rx = base + offs->rx;
+
+       if (cfg->lanes >= 2) {
+               qmp->tx2 = base + offs->tx2;
+               qmp->rx2 = base + offs->rx2;
+       }
+
+       qmp->num_pipe_clks = 2;
+       qmp->pipe_clks[0].id = "pipe";
+       qmp->pipe_clks[1].id = "pipediv2";
+
+       ret = devm_clk_bulk_get(dev, qmp->num_pipe_clks, qmp->pipe_clks);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
 static int qmp_pcie_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
-       struct device_node *child;
        struct phy_provider *phy_provider;
+       struct device_node *np;
        struct qmp_pcie *qmp;
        int ret;
 
@@ -2253,21 +2523,24 @@ static int qmp_pcie_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
-       child = of_get_next_available_child(dev->of_node, NULL);
-       if (!child)
-               return -EINVAL;
-
-       ret = qmp_pcie_parse_dt_legacy(qmp, child);
+       /* Check for legacy binding with child node. */
+       np = of_get_next_available_child(dev->of_node, NULL);
+       if (np) {
+               ret = qmp_pcie_parse_dt_legacy(qmp, np);
+       } else {
+               np = of_node_get(dev->of_node);
+               ret = qmp_pcie_parse_dt(qmp);
+       }
        if (ret)
                goto err_node_put;
 
-       ret = phy_pipe_clk_register(qmp, child);
+       ret = phy_pipe_clk_register(qmp, np);
        if (ret)
                goto err_node_put;
 
        qmp->mode = PHY_MODE_PCIE_RC;
 
-       qmp->phy = devm_phy_create(dev, child, &qmp_pcie_phy_ops);
+       qmp->phy = devm_phy_create(dev, np, &qmp_pcie_phy_ops);
        if (IS_ERR(qmp->phy)) {
                ret = PTR_ERR(qmp->phy);
                dev_err(dev, "failed to create PHY: %d\n", ret);
@@ -2276,14 +2549,14 @@ static int qmp_pcie_probe(struct platform_device *pdev)
 
        phy_set_drvdata(qmp->phy, qmp);
 
-       of_node_put(child);
+       of_node_put(np);
 
        phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
 
        return PTR_ERR_OR_ZERO(phy_provider);
 
 err_node_put:
-       of_node_put(child);
+       of_node_put(np);
        return ret;
 }
 
@@ -2304,6 +2577,12 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
                .compatible = "qcom,sc8180x-qmp-pcie-phy",
                .data = &sc8180x_pciephy_cfg,
        }, {
+               .compatible = "qcom,sc8280xp-qmp-gen3x1-pcie-phy",
+               .data = &sc8280xp_qmp_gen3x1_pciephy_cfg,
+       }, {
+               .compatible = "qcom,sc8280xp-qmp-gen3x2-pcie-phy",
+               .data = &sc8280xp_qmp_gen3x2_pciephy_cfg,
+       }, {
                .compatible = "qcom,sdm845-qhp-pcie-phy",
                .data = &sdm845_qhp_pciephy_cfg,
        }, {
index 2e19fb3..a469ae2 100644 (file)
@@ -8,6 +8,8 @@
 #define QCOM_PHY_QMP_PCS_PCIE_V5_H_
 
 /* Only for QMP V5 PHY - PCS_PCIE registers */
+#define QPHY_V5_PCS_PCIE_POWER_STATE_CONFIG2           0x0c
+#define QPHY_V5_PCS_PCIE_POWER_STATE_CONFIG4           0x14
 #define QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE         0x20
 #define QPHY_V5_PCS_PCIE_INT_AUX_CLK_CONFIG1           0x54
 #define QPHY_V5_PCS_PCIE_OSC_DTCT_ACTIONS              0x94