From nobody Tue Dec 16 16:35:16 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4BD3DC38A02 for ; Fri, 28 Oct 2022 13:37:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231274AbiJ1Nhm (ORCPT ); Fri, 28 Oct 2022 09:37:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43208 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231235AbiJ1Ngw (ORCPT ); Fri, 28 Oct 2022 09:36:52 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 998A11D8F3D; Fri, 28 Oct 2022 06:36:51 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 77FB96288D; Fri, 28 Oct 2022 13:36:50 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id AB664C4FF40; Fri, 28 Oct 2022 13:36:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1666964210; bh=1DOLRpBCXMsC1CLNbbIY7iZuk8xMt+gnpUh7sFM8oiw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=em9zwbCQ1hevIv2lQwrXWFMoKKsp373j5apm7QEOvXntlBlIvle89bUdeHCtM/13u l6jeGxBKRkBWeVjaRi3BgaQbJuu8Yui15QPvoA64TKgWf9yBZIvsHvZ99GcqIEAXVW fOyTureTeTtckrfW8Nzmj2s9GDgjfRs+yDFCWzYwyrItnBBE/ieXrCZq2UAZ7+/yEj OPPC/hSgFvGrKM1ym6Esh06KN5tbJepCZ6R4dERQUFyKXEn/rFBHudss/vLAGWTu+I wj6RPLnfC+dMuiq0FEVVYCeXxFt6Ug/hZl+7dZNxXKGkgCrLAH44OKCQEyAYvTjYVn Jy549K4yW3P2A== Received: from johan by xi.lan with local (Exim 4.94.2) (envelope-from ) id 1ooPXI-0004rZ-3O; Fri, 28 Oct 2022 15:36:36 +0200 From: Johan Hovold To: Vinod Koul Cc: Andy Gross , Bjorn Andersson , Konrad Dybcio , Rob Herring , Krzysztof Kozlowski , Dmitry Baryshkov , linux-arm-msm@vger.kernel.org, linux-phy@lists.infradead.org, linux-kernel@vger.kernel.org, Johan Hovold Subject: [PATCH v4 15/16] phy: qcom-qmp-pcie: add support for sc8280xp Date: Fri, 28 Oct 2022 15:36:02 +0200 Message-Id: <20221028133603.18470-16-johan+linaro@kernel.org> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221028133603.18470-1-johan+linaro@kernel.org> References: <20221028133603.18470-1-johan+linaro@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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. Signed-off-by: Johan Hovold Reviewed-by: Dmitry Baryshkov --- drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 299 +++++++++++++++++- .../phy/qualcomm/phy-qcom-qmp-pcs-pcie-v5.h | 2 + 2 files changed, 291 insertions(+), 10 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcom= m/phy-qcom-qmp-pcie.c index 758457943f2b..2ba57b230342 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c @@ -834,6 +834,143 @@ static const struct qmp_phy_init_tbl sc8180x_qmp_pcie= _pcs_misc_tbl[] =3D { QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1), }; =20 +static const struct qmp_phy_init_tbl sc8280xp_qmp_pcie_serdes_tbl[] =3D { + 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_tb= l[] =3D { + QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_BUF_ENABLE, 0x07), +}; + +static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x2_pcie_rc_serdes_tb= l[] =3D { + 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[] =3D= { + 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[] =3D= { + 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[] = =3D { + 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= [] =3D { + 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[] =3D= { + 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[] =3D= { + 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[] = =3D { + 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= [] =3D { + 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[] =3D { 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_gen4= x2_pcie_ep_pcs_misc_tbl[] =3D QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_OSC_DTCT_MODE2_CONFIG5, 0x08), }; =20 +struct qmp_pcie_offsets { + u16 serdes; + u16 pcs; + u16 pcs_misc; + u16 tx; + u16 rx; + u16 tx2; + u16 rx2; +}; + struct qmp_phy_cfg_tables { const struct qmp_phy_init_tbl *serdes; int serdes_num; @@ -1330,6 +1477,8 @@ struct qmp_phy_cfg_tables { struct qmp_phy_cfg { int lanes; =20 + const struct qmp_pcie_offsets *offsets; + /* Main init sequence for PHY blocks - serdes, tx, rx, pcs */ const struct qmp_phy_cfg_tables tables; /* @@ -1422,6 +1571,9 @@ static const char * const msm8996_phy_clk_l[] =3D { "aux", "cfg_ahb", "ref", }; =20 +static const char * const sc8280xp_pciephy_clk_l[] =3D { + "aux", "cfg_ahb", "ref", "rchng", +}; =20 static const char * const sdm845_pciephy_clk_l[] =3D { "aux", "cfg_ahb", "ref", "refgen", @@ -1441,6 +1593,16 @@ static const char * const sdm845_pciephy_reset_l[] = =3D { "phy", }; =20 +static const struct qmp_pcie_offsets qmp_pcie_offsets_v5 =3D { + .serdes =3D 0, + .pcs =3D 0x0200, + .pcs_misc =3D 0x0600, + .tx =3D 0x0e00, + .rx =3D 0x1000, + .tx2 =3D 0x1600, + .rx2 =3D 0x1800, +}; + static const struct qmp_phy_cfg ipq8074_pciephy_cfg =3D { .lanes =3D 1, =20 @@ -1700,6 +1862,76 @@ static const struct qmp_phy_cfg sc8180x_pciephy_cfg = =3D { .phy_status =3D PHYSTATUS, }; =20 +static const struct qmp_phy_cfg sc8280xp_qmp_gen3x1_pciephy_cfg =3D { + .lanes =3D 1, + + .offsets =3D &qmp_pcie_offsets_v5, + + .tables =3D { + .serdes =3D sc8280xp_qmp_pcie_serdes_tbl, + .serdes_num =3D ARRAY_SIZE(sc8280xp_qmp_pcie_serdes_tbl), + .tx =3D sc8280xp_qmp_gen3x1_pcie_tx_tbl, + .tx_num =3D ARRAY_SIZE(sc8280xp_qmp_gen3x1_pcie_tx_tbl), + .rx =3D sc8280xp_qmp_gen3x1_pcie_rx_tbl, + .rx_num =3D ARRAY_SIZE(sc8280xp_qmp_gen3x1_pcie_rx_tbl), + .pcs =3D sc8280xp_qmp_gen3x1_pcie_pcs_tbl, + .pcs_num =3D ARRAY_SIZE(sc8280xp_qmp_gen3x1_pcie_pcs_tbl), + .pcs_misc =3D sc8280xp_qmp_gen3x1_pcie_pcs_misc_tbl, + .pcs_misc_num =3D ARRAY_SIZE(sc8280xp_qmp_gen3x1_pcie_pcs_misc_tbl), + }, + + .tables_rc =3D &(const struct qmp_phy_cfg_tables) { + .serdes =3D sc8280xp_qmp_gen3x1_pcie_rc_serdes_tbl, + .serdes_num =3D ARRAY_SIZE(sc8280xp_qmp_gen3x1_pcie_rc_serdes_tbl), + }, + + .clk_list =3D sc8280xp_pciephy_clk_l, + .num_clks =3D ARRAY_SIZE(sc8280xp_pciephy_clk_l), + .reset_list =3D sdm845_pciephy_reset_l, + .num_resets =3D ARRAY_SIZE(sdm845_pciephy_reset_l), + .vreg_list =3D qmp_phy_vreg_l, + .num_vregs =3D ARRAY_SIZE(qmp_phy_vreg_l), + .regs =3D sm8250_pcie_regs_layout, + + .pwrdn_ctrl =3D SW_PWRDN | REFCLK_DRV_DSBL, + .phy_status =3D PHYSTATUS, +}; + +static const struct qmp_phy_cfg sc8280xp_qmp_gen3x2_pciephy_cfg =3D { + .lanes =3D 2, + + .offsets =3D &qmp_pcie_offsets_v5, + + .tables =3D { + .serdes =3D sc8280xp_qmp_pcie_serdes_tbl, + .serdes_num =3D ARRAY_SIZE(sc8280xp_qmp_pcie_serdes_tbl), + .tx =3D sc8280xp_qmp_gen3x2_pcie_tx_tbl, + .tx_num =3D ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_tx_tbl), + .rx =3D sc8280xp_qmp_gen3x2_pcie_rx_tbl, + .rx_num =3D ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_rx_tbl), + .pcs =3D sc8280xp_qmp_gen3x2_pcie_pcs_tbl, + .pcs_num =3D ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_pcs_tbl), + .pcs_misc =3D sc8280xp_qmp_gen3x2_pcie_pcs_misc_tbl, + .pcs_misc_num =3D ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_pcs_misc_tbl), + }, + + .tables_rc =3D &(const struct qmp_phy_cfg_tables) { + .serdes =3D sc8280xp_qmp_gen3x2_pcie_rc_serdes_tbl, + .serdes_num =3D ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_rc_serdes_tbl), + }, + + .clk_list =3D sc8280xp_pciephy_clk_l, + .num_clks =3D ARRAY_SIZE(sc8280xp_pciephy_clk_l), + .reset_list =3D sdm845_pciephy_reset_l, + .num_resets =3D ARRAY_SIZE(sdm845_pciephy_reset_l), + .vreg_list =3D qmp_phy_vreg_l, + .num_vregs =3D ARRAY_SIZE(qmp_phy_vreg_l), + .regs =3D sm8250_pcie_regs_layout, + + .pwrdn_ctrl =3D SW_PWRDN | REFCLK_DRV_DSBL, + .phy_status =3D PHYSTATUS, +}; + static const struct qmp_phy_cfg sdx55_qmp_pciephy_cfg =3D { .lanes =3D 2, =20 @@ -2220,11 +2452,49 @@ static int qmp_pcie_parse_dt_legacy(struct qmp_pcie= *qmp, struct device_node *np return 0; } =20 +static int qmp_pcie_parse_dt(struct qmp_pcie *qmp) +{ + struct platform_device *pdev =3D to_platform_device(qmp->dev); + const struct qmp_phy_cfg *cfg =3D qmp->cfg; + const struct qmp_pcie_offsets *offs =3D cfg->offsets; + struct device *dev =3D qmp->dev; + void __iomem *base; + int ret; + + if (!offs) + return -EINVAL; + + base =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + qmp->serdes =3D base + offs->serdes; + qmp->pcs =3D base + offs->pcs; + qmp->pcs_misc =3D base + offs->pcs_misc; + qmp->tx =3D base + offs->tx; + qmp->rx =3D base + offs->rx; + + if (cfg->lanes >=3D 2) { + qmp->tx2 =3D base + offs->tx2; + qmp->rx2 =3D base + offs->rx2; + } + + qmp->num_pipe_clks =3D 2; + qmp->pipe_clks[0].id =3D "pipe"; + qmp->pipe_clks[1].id =3D "pipediv2"; + + ret =3D 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 =3D &pdev->dev; - struct device_node *child; struct phy_provider *phy_provider; + struct device_node *np; struct qmp_pcie *qmp; int ret; =20 @@ -2253,21 +2523,24 @@ static int qmp_pcie_probe(struct platform_device *p= dev) if (ret) return ret; =20 - child =3D of_get_next_available_child(dev->of_node, NULL); - if (!child) - return -EINVAL; - - ret =3D qmp_pcie_parse_dt_legacy(qmp, child); + /* Check for legacy binding with child node. */ + np =3D of_get_next_available_child(dev->of_node, NULL); + if (np) { + ret =3D qmp_pcie_parse_dt_legacy(qmp, np); + } else { + np =3D of_node_get(dev->of_node); + ret =3D qmp_pcie_parse_dt(qmp); + } if (ret) goto err_node_put; =20 - ret =3D phy_pipe_clk_register(qmp, child); + ret =3D phy_pipe_clk_register(qmp, np); if (ret) goto err_node_put; =20 qmp->mode =3D PHY_MODE_PCIE_RC; =20 - qmp->phy =3D devm_phy_create(dev, child, &qmp_pcie_phy_ops); + qmp->phy =3D devm_phy_create(dev, np, &qmp_pcie_phy_ops); if (IS_ERR(qmp->phy)) { ret =3D 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 *p= dev) =20 phy_set_drvdata(qmp->phy, qmp); =20 - of_node_put(child); + of_node_put(np); =20 phy_provider =3D devm_of_phy_provider_register(dev, of_phy_simple_xlate); =20 return PTR_ERR_OR_ZERO(phy_provider); =20 err_node_put: - of_node_put(child); + of_node_put(np); return ret; } =20 @@ -2303,6 +2576,12 @@ static const struct of_device_id qmp_pcie_of_match_t= able[] =3D { }, { .compatible =3D "qcom,sc8180x-qmp-pcie-phy", .data =3D &sc8180x_pciephy_cfg, + }, { + .compatible =3D "qcom,sc8280xp-qmp-gen3x1-pcie-phy", + .data =3D &sc8280xp_qmp_gen3x1_pciephy_cfg, + }, { + .compatible =3D "qcom,sc8280xp-qmp-gen3x2-pcie-phy", + .data =3D &sc8280xp_qmp_gen3x2_pciephy_cfg, }, { .compatible =3D "qcom,sdm845-qhp-pcie-phy", .data =3D &sdm845_qhp_pciephy_cfg, diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v5.h b/drivers/phy/= qualcomm/phy-qcom-qmp-pcs-pcie-v5.h index 2e19fb3f051e..a469ae2a10a1 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v5.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v5.h @@ -8,6 +8,8 @@ #define QCOM_PHY_QMP_PCS_PCIE_V5_H_ =20 /* 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 --=20 2.37.3