2020-07-05 09:19:00

by Sivaprakash Murugesan

[permalink] [raw]
Subject: [PATCH 0/9] Add PCIe support for IPQ8074

IPQ8074 has two PCIe ports both are based on synopsis designware PCIe
controller. while it was assumed that PCIe support for IPQ8074 was already
available. PCIe was not functional until now.

This patch series adds support for PCIe ports on IPQ8074.

First PCIe port is of gen2 synposis version is 2_3_2 which has already been
enabled. But it had some problems on phy init and needed dt updates.

Second PCIe port is gen3 synopsis version is 2_9_0. This series adds
support for this PCIe port while fixing dt nodes.

Patch 1 on this series depends on qcom pcie bindings patch
https://lkml.org/lkml/2020/6/24/162

Sivaprakash Murugesan (9):
dt-bindings: pci: Add ipq8074 gen3 pci compatible
dt-bindings: phy: qcom,qmp: Add dt-binding for ipq8074 gen3 pcie phy
clk: qcom: ipq8074: Add missing bindings for pcie
clk: qcom: ipq8074: Add missing clocks for pcie
phy: qcom-qmp: use correct values for ipq8074 gen2 pcie phy init
phy: qcom-qmp: Add compatible for ipq8074 pcie gen3 qmp phy
pci: dwc: qcom: do phy power on before pcie init
pci: qcom: Add support for ipq8074 pci controller
arm64: dts: ipq8074: Fixup pcie dts nodes

.../devicetree/bindings/pci/qcom,pcie.yaml | 47 ++++++
.../devicetree/bindings/phy/qcom,qmp-phy.yaml | 1 +
arch/arm64/boot/dts/qcom/ipq8074-hk01.dts | 8 +-
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 109 ++++++++----
drivers/clk/qcom/gcc-ipq8074.c | 60 +++++++
drivers/pci/controller/dwc/pcie-qcom.c | 187 +++++++++++++++++++-
drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h | 132 +++++++++++++++
drivers/phy/qualcomm/phy-qcom-qmp.c | 188 ++++++++++++++++++++-
drivers/phy/qualcomm/phy-qcom-qmp.h | 2 +
include/dt-bindings/clock/qcom,gcc-ipq8074.h | 4 +
10 files changed, 683 insertions(+), 55 deletions(-)
create mode 100644 drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h

--
2.7.4


2020-07-05 09:19:07

by Sivaprakash Murugesan

[permalink] [raw]
Subject: [PATCH 8/9] pci: qcom: Add support for ipq8074 pci controller

ipq8074 has one gen2 and one gen3 pcie port, with support for gen2 port
is already available add support for pcie gen3 port.

Co-developed-by: Selvam Sathappan Periakaruppan <[email protected]>
Signed-off-by: Selvam Sathappan Periakaruppan <[email protected]>
Signed-off-by: Sivaprakash Murugesan <[email protected]>
---
drivers/pci/controller/dwc/pcie-qcom.c | 175 ++++++++++++++++++++++++++++++++-
1 file changed, 174 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index aa52a2124760..1a6fafdb2642 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -39,8 +39,17 @@
#define L23_CLK_RMV_DIS BIT(2)
#define L1_CLK_RMV_DIS BIT(1)

+#define PCIE_ATU_CR1_OUTBOUND_6_GEN3 0xC00
+#define PCIE_ATU_CR2_OUTBOUND_6_GEN3 0xC04
+#define PCIE_ATU_LIMIT_OUTBOUND_6_GEN3 0xC10
+#define PCIE_ATU_CR1_OUTBOUND_7_GEN3 0xE00
+#define PCIE_ATU_CR2_OUTBOUND_7_GEN3 0xE04
+#define PCIE_ATU_LOWER_BASE_OUTBOUND_7_GEN3 0xE08
+#define PCIE_ATU_LIMIT_OUTBOUND_7_GEN3 0xE10
+
#define PCIE20_COMMAND_STATUS 0x04
#define CMD_BME_VAL 0x4
+#define BUS_MASTER_EN 0x7
#define PCIE20_DEVICE_CONTROL2_STATUS2 0x98
#define PCIE_CAP_CPL_TIMEOUT_DISABLE 0x10

@@ -49,6 +58,15 @@
#define PCIE20_PARF_DBI_BASE_ADDR 0x168
#define PCIE20_PARF_SLV_ADDR_SPACE_SIZE 0x16C
#define PCIE20_PARF_MHI_CLOCK_RESET_CTRL 0x174
+
+#define AHB_CLK_EN BIT(0)
+#define MSTR_AXI_CLK_EN BIT(1)
+#define BYPASS BIT(4)
+
+#define PCIE20_LNK_CONTROL2_LINK_STATUS2 0xA0
+#define PCIE_CAP_CURR_DEEMPHASIS BIT(16)
+#define SPEED_GEN3 0x3
+
#define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT 0x178
#define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1A8
#define PCIE20_PARF_LTSSM 0x1B0
@@ -56,6 +74,9 @@
#define PCIE20_PARF_BDF_TRANSLATE_CFG 0x24C
#define PCIE20_PARF_DEVICE_TYPE 0x1000

+#define PCIE20_PARF_BDF_TO_SID_TABLE 0x2000
+#define BDF_TO_SID_TABLE_SIZE 0x100
+
#define PCIE20_ELBI_SYS_CTRL 0x04
#define PCIE20_ELBI_SYS_CTRL_LT_ENABLE BIT(0)

@@ -83,6 +104,10 @@

#define DEVICE_TYPE_RC 0x4

+#define PCIE30_GEN3_RELATED_OFF 0x890
+#define RXEQ_RGRDLESS_RXTS BIT(13)
+#define GEN3_ZRXDC_NONCOMPL BIT(0)
+
#define QCOM_PCIE_2_1_0_MAX_SUPPLY 3
struct qcom_pcie_resources_2_1_0 {
struct clk *iface_clk;
@@ -149,6 +174,11 @@ struct qcom_pcie_resources_2_7_0 {
struct clk *pipe_clk;
};

+struct qcom_pcie_resources_2_9_0 {
+ struct clk_bulk_data clks[7];
+ struct reset_control *rst[8];
+};
+
union qcom_pcie_resources {
struct qcom_pcie_resources_1_0_0 v1_0_0;
struct qcom_pcie_resources_2_1_0 v2_1_0;
@@ -156,6 +186,7 @@ union qcom_pcie_resources {
struct qcom_pcie_resources_2_3_3 v2_3_3;
struct qcom_pcie_resources_2_4_0 v2_4_0;
struct qcom_pcie_resources_2_7_0 v2_7_0;
+ struct qcom_pcie_resources_2_9_0 v2_9_0;
};

struct qcom_pcie;
@@ -1207,6 +1238,133 @@ static void qcom_pcie_post_deinit_2_7_0(struct qcom_pcie *pcie)
clk_disable_unprepare(res->pipe_clk);
}

+static int qcom_pcie_get_resources_2_9_0(struct qcom_pcie *pcie)
+{
+ struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
+ struct dw_pcie *pci = pcie->pci;
+ struct device *dev = pci->dev;
+ int ret, i;
+ const char *rst_names[] = { "pipe", "sleep", "sticky", "axi_m",
+ "axi_s", "ahb", "axi_m_sticky",
+ "axi_s_sticky" };
+
+ res->clks[0].id = "iface";
+ res->clks[1].id = "axi_m";
+ res->clks[2].id = "axi_s";
+ res->clks[3].id = "ahb";
+ res->clks[4].id = "aux";
+ res->clks[5].id = "axi_bridge";
+ res->clks[6].id = "rchng";
+
+ ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < ARRAY_SIZE(rst_names); i++) {
+ res->rst[i] = devm_reset_control_get(dev, rst_names[i]);
+ if (IS_ERR(res->rst[i]))
+ return PTR_ERR(res->rst[i]);
+ }
+
+ return 0;
+}
+
+static int qcom_pcie_init_2_9_0(struct qcom_pcie *pcie)
+{
+ struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
+ struct dw_pcie *pci = pcie->pci;
+ struct device *dev = pci->dev;
+ int i, ret;
+ u32 val;
+
+ for (i = 0; i < ARRAY_SIZE(res->rst); i++) {
+ ret = reset_control_assert(res->rst[i]);
+ if (ret) {
+ dev_err(dev, "reset #%d assert failed (%d)\n", i, ret);
+ return ret;
+ }
+ }
+
+ usleep_range(2000, 2500);
+
+ for (i = 0; i < ARRAY_SIZE(res->rst); i++) {
+ ret = reset_control_deassert(res->rst[i]);
+ if (ret) {
+ dev_err(dev, "reset #%d deassert failed (%d)\n", i,
+ ret);
+ return ret;
+ }
+ }
+
+ /*
+ * Don't have a way to see if the reset has completed.
+ * Wait for some time.
+ */
+ usleep_range(2000, 2500);
+
+ ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
+ if (ret)
+ return ret;
+
+ /* Parf config */
+ writel(SLV_ADDR_SPACE_SZ,
+ pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
+
+ val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
+ val &= ~BIT(0);
+ writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
+
+ writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
+ writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
+ writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
+ pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
+
+ writel(RXEQ_RGRDLESS_RXTS | GEN3_ZRXDC_NONCOMPL,
+ pci->dbi_base + PCIE30_GEN3_RELATED_OFF);
+ writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
+ | SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
+ AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
+ pcie->parf + PCIE20_PARF_SYS_CTRL);
+ writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
+
+ /* DBI config */
+ writel(BUS_MASTER_EN, pci->dbi_base + PCIE20_COMMAND_STATUS);
+
+ writel(DBI_RO_WR_EN, pci->dbi_base + PCIE20_MISC_CONTROL_1_REG);
+ writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + PCIE20_CAP_LINK_1);
+
+ /* Configure PCIe link capabilities for ASPM */
+ val = readl(pci->dbi_base + PCIE20_CAP_LINK_CAPABILITIES);
+ val &= ~PCIE20_CAP_ACTIVE_STATE_LINK_PM_SUPPORT;
+ writel(val, pci->dbi_base + PCIE20_CAP_LINK_CAPABILITIES);
+
+ writel(PCIE_CAP_CPL_TIMEOUT_DISABLE, pci->dbi_base +
+ PCIE20_DEVICE_CONTROL2_STATUS2);
+
+ writel(PCIE_CAP_CURR_DEEMPHASIS | SPEED_GEN3,
+ pci->dbi_base + PCIE20_LNK_CONTROL2_LINK_STATUS2);
+
+ for (i = 0 ; i < BDF_TO_SID_TABLE_SIZE ; i++)
+ writel(0x0, pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE + (4 * i));
+
+ writel(0x4, pci->atu_base + PCIE_ATU_CR1_OUTBOUND_6_GEN3);
+ writel(0x90000000, pci->atu_base + PCIE_ATU_CR2_OUTBOUND_6_GEN3);
+ writel(0x00107FFFF, pci->atu_base + PCIE_ATU_LIMIT_OUTBOUND_6_GEN3);
+ writel(0x5, pci->atu_base + PCIE_ATU_CR1_OUTBOUND_7_GEN3);
+ writel(0x90000000, pci->atu_base + PCIE_ATU_CR2_OUTBOUND_7_GEN3);
+ writel(0x200000, pci->atu_base + PCIE_ATU_LOWER_BASE_OUTBOUND_7_GEN3);
+ writel(0x7FFFFF, pci->atu_base + PCIE_ATU_LIMIT_OUTBOUND_7_GEN3);
+
+ return 0;
+}
+
+static void qcom_pcie_deinit_2_9_0(struct qcom_pcie *pcie)
+{
+ struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
+
+ clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
+}
+
static int qcom_pcie_link_up(struct dw_pcie *pci)
{
u16 val = readw(pci->dbi_base + PCIE20_CAP + PCI_EXP_LNKSTA);
@@ -1246,7 +1404,6 @@ static int qcom_pcie_host_init(struct pcie_port *pp)
ret = qcom_pcie_establish_link(pcie);
if (ret)
goto err;
-
return 0;
err:
qcom_ep_reset_assert(pcie);
@@ -1316,6 +1473,14 @@ static const struct qcom_pcie_ops ops_2_7_0 = {
.post_deinit = qcom_pcie_post_deinit_2_7_0,
};

+/* Qcom IP rev.: 2.9.0 Synopsys IP rev.: 5.00a */
+static const struct qcom_pcie_ops ops_2_9_0 = {
+ .get_resources = qcom_pcie_get_resources_2_9_0,
+ .init = qcom_pcie_init_2_9_0,
+ .deinit = qcom_pcie_deinit_2_9_0,
+ .ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
+};
+
static const struct dw_pcie_ops dw_pcie_ops = {
.link_up = qcom_pcie_link_up,
};
@@ -1358,6 +1523,13 @@ static int qcom_pcie_probe(struct platform_device *pdev)
goto err_pm_runtime_put;
}

+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "atu");
+ pci->atu_base = devm_pci_remap_cfg_resource(dev, res);
+ if (IS_ERR(pci->atu_base) && pcie->ops == &ops_2_9_0) {
+ ret = PTR_ERR(pci->atu_base);
+ goto err_pm_runtime_put;
+ }
+
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "parf");
pcie->parf = devm_ioremap_resource(dev, res);
if (IS_ERR(pcie->parf)) {
@@ -1432,6 +1604,7 @@ static const struct of_device_id qcom_pcie_match[] = {
{ .compatible = "qcom,pcie-ipq4019", .data = &ops_2_4_0 },
{ .compatible = "qcom,pcie-qcs404", .data = &ops_2_4_0 },
{ .compatible = "qcom,pcie-sdm845", .data = &ops_2_7_0 },
+ { .compatible = "qcom,pcie-ipq8074-gen3", .data = &ops_2_9_0 },
{ }
};

--
2.7.4

2020-07-05 09:19:13

by Sivaprakash Murugesan

[permalink] [raw]
Subject: [PATCH 5/9] phy: qcom-qmp: use correct values for ipq8074 gen2 pcie phy init

There were some problem in ipq8074 gen2 pcie phy init sequence, fix
these to make gen2 pcie port on ipq8074 to work.

Fixes: eef243d04b2b6 ("phy: qcom-qmp: Add support for IPQ8074")

Cc: [email protected]
Co-developed-by: Selvam Sathappan Periakaruppan <[email protected]>
Signed-off-by: Selvam Sathappan Periakaruppan <[email protected]>
Signed-off-by: Sivaprakash Murugesan <[email protected]>
---
drivers/phy/qualcomm/phy-qcom-qmp.c | 16 +++++++++-------
drivers/phy/qualcomm/phy-qcom-qmp.h | 2 ++
2 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index e91040af3394..ba277136f52b 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -504,8 +504,8 @@ static const struct qmp_phy_init_tbl ipq8074_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0xf),
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x1),
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x0),
- QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0x1f),
- QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x1f),
QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x6),
QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0xf),
QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x0),
@@ -531,7 +531,6 @@ static const struct qmp_phy_init_tbl ipq8074_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x0),
QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x1),
- QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0xa),
QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x1),
QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x1),
@@ -540,7 +539,6 @@ static const struct qmp_phy_init_tbl ipq8074_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x2f),
QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x19),
QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV, 0x19),
- QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x7),
};

static const struct qmp_phy_init_tbl ipq8074_pcie_tx_tbl[] = {
@@ -548,6 +546,8 @@ static const struct qmp_phy_init_tbl ipq8074_pcie_tx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x6),
QMP_PHY_INIT_CFG(QSERDES_TX_RES_CODE_LANE_OFFSET, 0x2),
QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2, 0x12),
+ QMP_PHY_INIT_CFG(QSERDES_TX_EMP_POST1_LVL, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_TX_SLEW_CNTL, 0x0a),
};

static const struct qmp_phy_init_tbl ipq8074_pcie_rx_tbl[] = {
@@ -558,7 +558,6 @@ static const struct qmp_phy_init_tbl ipq8074_pcie_rx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xdb),
QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x4),
- QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN_HALF, 0x4),
};

static const struct qmp_phy_init_tbl ipq8074_pcie_pcs_tbl[] = {
@@ -1673,6 +1672,9 @@ static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
.pwrdn_ctrl = SW_PWRDN,
};

+static const char * const ipq8074_pciephy_clk_l[] = {
+ "aux", "cfg_ahb",
+};
/* list of resets */
static const char * const ipq8074_pciephy_reset_l[] = {
"phy", "common",
@@ -1690,8 +1692,8 @@ static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
.rx_tbl_num = ARRAY_SIZE(ipq8074_pcie_rx_tbl),
.pcs_tbl = ipq8074_pcie_pcs_tbl,
.pcs_tbl_num = ARRAY_SIZE(ipq8074_pcie_pcs_tbl),
- .clk_list = NULL,
- .num_clks = 0,
+ .clk_list = ipq8074_pciephy_clk_l,
+ .num_clks = ARRAY_SIZE(ipq8074_pciephy_clk_l),
.reset_list = ipq8074_pciephy_reset_l,
.num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
.vreg_list = NULL,
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h
index 6d017a0c0c8d..832b3d098403 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
@@ -77,6 +77,8 @@
#define QSERDES_COM_CORECLK_DIV_MODE1 0x1bc

/* Only for QMP V2 PHY - TX registers */
+#define QSERDES_TX_EMP_POST1_LVL 0x018
+#define QSERDES_TX_SLEW_CNTL 0x040
#define QSERDES_TX_RES_CODE_LANE_OFFSET 0x054
#define QSERDES_TX_DEBUG_BUS_SEL 0x064
#define QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN 0x068
--
2.7.4

2020-07-05 09:19:22

by Sivaprakash Murugesan

[permalink] [raw]
Subject: [PATCH 6/9] phy: qcom-qmp: Add compatible for ipq8074 pcie gen3 qmp phy

ipq8074 has two pcie ports, one gen2 and one gen3 ports. with phy
support already available for gen2 pcie ports add support for pcie gen3
port phy.

Co-developed-by: Selvam Sathappan Periakaruppan <[email protected]>
Signed-off-by: Selvam Sathappan Periakaruppan <[email protected]>
Signed-off-by: Sivaprakash Murugesan <[email protected]>
---
drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h | 137 ++++++++++++++++++++++++
drivers/phy/qualcomm/phy-qcom-qmp.c | 172 +++++++++++++++++++++++++++++-
2 files changed, 307 insertions(+), 2 deletions(-)
create mode 100644 drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h

diff --git a/drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h b/drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h
new file mode 100644
index 000000000000..bb567673d9b5
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h
@@ -0,0 +1,137 @@
+/* SPDX-License-Identifier: GPL-2.0*
+ *
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef PHY_QCOM_PCIE_H
+
+/* QMP V2 PCIE PHY - Found in IPQ8074 gen3 port - QSERDES PLL registers */
+#define QSERDES_PLL_BG_TIMER 0x00c
+#define QSERDES_PLL_SSC_PER1 0x01c
+#define QSERDES_PLL_SSC_PER2 0x020
+#define QSERDES_PLL_SSC_STEP_SIZE1_MODE0 0x024
+#define QSERDES_PLL_SSC_STEP_SIZE2_MODE0 0x028
+#define QSERDES_PLL_SSC_STEP_SIZE1_MODE1 0x02c
+#define QSERDES_PLL_SSC_STEP_SIZE2_MODE1 0x030
+#define QSERDES_PLL_BIAS_EN_CLKBUFLR_EN 0x03c
+#define QSERDES_PLL_CLK_ENABLE1 0x040
+#define QSERDES_PLL_SYS_CLK_CTRL 0x044
+#define QSERDES_PLL_SYSCLK_BUF_ENABLE 0x048
+#define QSERDES_PLL_PLL_IVCO 0x050
+#define QSERDES_PLL_LOCK_CMP1_MODE0 0x054
+#define QSERDES_PLL_LOCK_CMP2_MODE0 0x058
+#define QSERDES_PLL_LOCK_CMP1_MODE1 0x060
+#define QSERDES_PLL_LOCK_CMP2_MODE1 0x064
+#define QSERDES_PLL_BG_TRIM 0x074
+#define QSERDES_PLL_CLK_EP_DIV_MODE0 0x078
+#define QSERDES_PLL_CLK_EP_DIV_MODE1 0x07c
+#define QSERDES_PLL_CP_CTRL_MODE0 0x080
+#define QSERDES_PLL_CP_CTRL_MODE1 0x084
+#define QSERDES_PLL_PLL_RCTRL_MODE0 0x088
+#define QSERDES_PLL_PLL_RCTRL_MODE1 0x08C
+#define QSERDES_PLL_PLL_CCTRL_MODE0 0x090
+#define QSERDES_PLL_PLL_CCTRL_MODE1 0x094
+#define QSERDES_PLL_BIAS_EN_CTRL_BY_PSM 0x0a4
+#define QSERDES_PLL_SYSCLK_EN_SEL 0x0a8
+#define QSERDES_PLL_RESETSM_CNTRL 0x0b0
+#define QSERDES_PLL_LOCK_CMP_EN 0x0c4
+#define QSERDES_PLL_DEC_START_MODE0 0x0cc
+#define QSERDES_PLL_DEC_START_MODE1 0x0d0
+#define QSERDES_PLL_DIV_FRAC_START1_MODE0 0x0d8
+#define QSERDES_PLL_DIV_FRAC_START2_MODE0 0x0dc
+#define QSERDES_PLL_DIV_FRAC_START3_MODE0 0x0e0
+#define QSERDES_PLL_DIV_FRAC_START1_MODE1 0x0e4
+#define QSERDES_PLL_DIV_FRAC_START2_MODE1 0x0e8
+#define QSERDES_PLL_DIV_FRAC_START3_MODE1 0x0eC
+#define QSERDES_PLL_INTEGLOOP_GAIN0_MODE0 0x100
+#define QSERDES_PLL_INTEGLOOP_GAIN1_MODE0 0x104
+#define QSERDES_PLL_INTEGLOOP_GAIN0_MODE1 0x108
+#define QSERDES_PLL_INTEGLOOP_GAIN1_MODE1 0x10c
+#define QSERDES_PLL_VCO_TUNE_MAP 0x120
+#define QSERDES_PLL_VCO_TUNE1_MODE0 0x124
+#define QSERDES_PLL_VCO_TUNE2_MODE0 0x128
+#define QSERDES_PLL_VCO_TUNE1_MODE1 0x12c
+#define QSERDES_PLL_VCO_TUNE2_MODE1 0x130
+#define QSERDES_PLL_VCO_TUNE_TIMER1 0x13c
+#define QSERDES_PLL_VCO_TUNE_TIMER2 0x140
+#define QSERDES_PLL_CLK_SELECT 0x16c
+#define QSERDES_PLL_HSCLK_SEL 0x170
+#define QSERDES_PLL_CORECLK_DIV 0x17c
+#define QSERDES_PLL_CORE_CLK_EN 0x184
+#define QSERDES_PLL_CMN_CONFIG 0x18c
+#define QSERDES_PLL_SVS_MODE_CLK_SEL 0x194
+#define QSERDES_PLL_CORECLK_DIV_MODE1 0x1b4
+
+/* QMP V2 PCIE PHY - Found in IPQ8074 gen3 port - - QSERDES TX registers */
+#define QSERDES_TX0_RES_CODE_LANE_OFFSET_TX 0x03c
+#define QSERDES_TX0_HIGHZ_DRVR_EN 0x058
+#define QSERDES_TX0_LANE_MODE_1 0x084
+#define QSERDES_TX0_RCV_DETECT_LVL_2 0x09c
+
+/* QMP V2 PCIE PHY - Found in IPQ8074 gen3 port - QSERDES RX registers */
+#define QSERDES_RX0_UCDR_FO_GAIN 0x008
+#define QSERDES_RX0_UCDR_SO_GAIN 0x014
+#define QSERDES_RX0_UCDR_SO_SATURATION_AND_ENABLE 0x034
+#define QSERDES_RX0_UCDR_PI_CONTROLS 0x044
+#define QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL2 0x0ec
+#define QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL3 0x0f0
+#define QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL4 0x0f4
+#define QSERDES_RX0_RX_IDAC_TSETTLE_LOW 0x0f8
+#define QSERDES_RX0_RX_IDAC_TSETTLE_HIGH 0x0fc
+#define QSERDES_RX0_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x110
+#define QSERDES_RX0_RX_OFFSET_ADAPTOR_CNTRL2 0x114
+#define QSERDES_RX0_SIGDET_ENABLES 0x118
+#define QSERDES_RX0_SIGDET_CNTRL 0x11c
+#define QSERDES_RX0_SIGDET_DEGLITCH_CNTRL 0x124
+#define QSERDES_RX0_RX_MODE_00_LOW 0x170
+#define QSERDES_RX0_RX_MODE_00_HIGH 0x174
+#define QSERDES_RX0_RX_MODE_00_HIGH2 0x178
+#define QSERDES_RX0_RX_MODE_00_HIGH3 0x17c
+#define QSERDES_RX0_RX_MODE_00_HIGH4 0x180
+#define QSERDES_RX0_RX_MODE_01_LOW 0x184
+#define QSERDES_RX0_RX_MODE_01_HIGH 0x188
+#define QSERDES_RX0_RX_MODE_01_HIGH2 0x18c
+#define QSERDES_RX0_RX_MODE_01_HIGH3 0x190
+#define QSERDES_RX0_RX_MODE_01_HIGH4 0x194
+#define QSERDES_RX0_RX_MODE_10_LOW 0x198
+#define QSERDES_RX0_RX_MODE_10_HIGH 0x19c
+#define QSERDES_RX0_RX_MODE_10_HIGH2 0x1a0
+#define QSERDES_RX0_RX_MODE_10_HIGH3 0x1a4
+#define QSERDES_RX0_RX_MODE_10_HIGH4 0x1a8
+#define QSERDES_RX0_DFE_EN_TIMER 0x1b4
+
+/* QMP V2 PCIE PHY - Found in IPQ8074 gen3 port - PCS registers */
+
+#define PCS_COM_FLL_CNTRL1 0x098
+#define PCS_COM_FLL_CNTRL2 0x09c
+#define PCS_COM_FLL_CNT_VAL_L 0x0a0
+#define PCS_COM_FLL_CNT_VAL_H_TOL 0x0a4
+#define PCS_COM_FLL_MAN_CODE 0x0a8
+#define PCS_COM_REFGEN_REQ_CONFIG1 0x0dc
+#define PCS_COM_G12S1_TXDEEMPH_M3P5DB 0x16c
+#define PCS_COM_RX_SIGDET_LVL 0x188
+#define PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_L 0x1a4
+#define PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_H 0x1a8
+#define PCS_COM_RX_DCC_CAL_CONFIG 0x1d8
+#define PCS_COM_EQ_CONFIG5 0x1ec
+
+/* QMP V2 PCIE PHY - Found in IPQ8074 gen3 port - PCS Misc registers */
+
+#define PCS_PCIE_POWER_STATE_CONFIG2 0x40c
+#define PCS_PCIE_POWER_STATE_CONFIG4 0x414
+#define PCS_PCIE_ENDPOINT_REFCLK_DRIVE 0x41c
+#define PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L 0x440
+#define PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_H 0x444
+#define PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L 0x448
+#define PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_H 0x44c
+#define PCS_PCIE_OSC_DTCT_CONFIG2 0x45c
+#define PCS_PCIE_OSC_DTCT_MODE2_CONFIG2 0x478
+#define PCS_PCIE_OSC_DTCT_MODE2_CONFIG4 0x480
+#define PCS_PCIE_OSC_DTCT_MODE2_CONFIG5 0x484
+#define PCS_PCIE_OSC_DTCT_ACTIONS 0x490
+#define PCS_PCIE_EQ_CONFIG1 0x4a0
+#define PCS_PCIE_EQ_CONFIG2 0x4a4
+#define PCS_PCIE_PRESET_P10_PRE 0x4bc
+#define PCS_PCIE_PRESET_P10_POST 0x4e0
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index ba277136f52b..2f513a8c58c7 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -23,6 +23,7 @@
#include <dt-bindings/phy/phy.h>

#include "phy-qcom-qmp.h"
+#include "phy-qcom-pcie3-qmp.h"

/* QPHY_SW_RESET bit */
#define SW_RESET BIT(0)
@@ -576,6 +577,132 @@ static const struct qmp_phy_init_tbl ipq8074_pcie_pcs_tbl[] = {
QMP_PHY_INIT_CFG_L(QPHY_START_CTRL, 0x3),
};

+static const struct qmp_phy_init_tbl ipq8074_pcie_gen3_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),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x31),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_IVCO, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TRIM, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CMN_CONFIG, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP_EN, 0x42),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_RESETSM_CNTRL, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_MAP, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_TIMER1, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_TIMER2, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x30),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x21),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE0, 0x82),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE0, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE0, 0x355),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE0, 0x35555),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE0, 0x1a),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE0, 0x1a0a),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE0, 0xb),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE0, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE0, 0x28),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN1_MODE0, 0x0),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE0, 0x40),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE0, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE0, 0x24),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV, 0xa),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x32),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SYS_CLK_CTRL, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_BUF_ENABLE, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_EN_SEL, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TIMER, 0xa),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x1),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE1, 0x68),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE1, 0x2),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE1, 0x2aa),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE1, 0x2aaab),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x90),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE1, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE1, 0x3414),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE1, 0x0b),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE1, 0x28),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN1_MODE1, 0x0),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE1, 0x40),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE1, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE1, 0xb4),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x0),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV_MODE1, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_EP_DIV_MODE0, 0x19),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_EP_DIV_MODE1, 0x28),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x90),
+};
+
+static const struct qmp_phy_init_tbl ipq8074_pcie_gen3_tx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_TX0_RES_CODE_LANE_OFFSET_TX, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_TX0_RCV_DETECT_LVL_2, 0x12),
+ QMP_PHY_INIT_CFG(QSERDES_TX0_HIGHZ_DRVR_EN, 0x10),
+ QMP_PHY_INIT_CFG(QSERDES_TX0_LANE_MODE_1, 0x06),
+};
+
+static const struct qmp_phy_init_tbl ipq8074_pcie_gen3_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_CNTRL, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_ENABLES, 0x1c),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_DEGLITCH_CNTRL, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL2, 0xe),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL3, 0x4),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL4, 0x1b),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_DFE_EN_TIMER, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_PI_CONTROLS, 0x70),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x73),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_LOW, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH2, 0xc8),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH3, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH4, 0xb1),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_LOW, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH2, 0xc8),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH3, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH4, 0xb1),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_LOW, 0xf0),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH, 0x2),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH2, 0x2f),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH3, 0xd3),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH4, 0x40),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_IDAC_TSETTLE_HIGH, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_IDAC_TSETTLE_LOW, 0xc0),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_FO_GAIN, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_SO_GAIN, 0x02),
+};
+
+static const struct qmp_phy_init_tbl ipq8074_pcie_gen3_pcs_tbl[] = {
+ QMP_PHY_INIT_CFG(PCS_COM_FLL_CNTRL2, 0x83),
+ QMP_PHY_INIT_CFG(PCS_COM_FLL_CNT_VAL_L, 0x9),
+ QMP_PHY_INIT_CFG(PCS_COM_FLL_CNT_VAL_H_TOL, 0x42),
+ QMP_PHY_INIT_CFG(PCS_COM_FLL_MAN_CODE, 0x40),
+ QMP_PHY_INIT_CFG(PCS_COM_FLL_CNTRL1, 0x01),
+ QMP_PHY_INIT_CFG(PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_H, 0x0),
+ QMP_PHY_INIT_CFG(PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x1),
+ QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_ACTIONS, 0x0),
+ QMP_PHY_INIT_CFG(PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_H, 0x00),
+ QMP_PHY_INIT_CFG(PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
+ QMP_PHY_INIT_CFG(PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_H, 0x00),
+ QMP_PHY_INIT_CFG(PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
+ QMP_PHY_INIT_CFG(PCS_PCIE_EQ_CONFIG1, 0x11),
+ QMP_PHY_INIT_CFG(PCS_PCIE_EQ_CONFIG2, 0xb),
+ QMP_PHY_INIT_CFG(PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
+ QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_CONFIG2, 0x52),
+ QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_MODE2_CONFIG2, 0x50),
+ QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_MODE2_CONFIG4, 0x1a),
+ QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_MODE2_CONFIG5, 0x6),
+ QMP_PHY_INIT_CFG(PCS_COM_G12S1_TXDEEMPH_M3P5DB, 0x10),
+ QMP_PHY_INIT_CFG(PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
+ QMP_PHY_INIT_CFG(PCS_COM_RX_DCC_CAL_CONFIG, 0x01),
+ QMP_PHY_INIT_CFG(PCS_COM_RX_SIGDET_LVL, 0xaa),
+ QMP_PHY_INIT_CFG(PCS_COM_REFGEN_REQ_CONFIG1, 0x0d),
+};
static const struct qmp_phy_init_tbl sdm845_qmp_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),
@@ -1710,6 +1837,36 @@ static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
.pwrdn_delay_max = 1005, /* us */
};

+static const struct qmp_phy_cfg ipq8074_pciephy_gen3_cfg = {
+ .type = PHY_TYPE_PCIE,
+ .nlanes = 1,
+
+ .serdes_tbl = ipq8074_pcie_gen3_serdes_tbl,
+ .serdes_tbl_num = ARRAY_SIZE(ipq8074_pcie_gen3_serdes_tbl),
+ .tx_tbl = ipq8074_pcie_gen3_tx_tbl,
+ .tx_tbl_num = ARRAY_SIZE(ipq8074_pcie_gen3_tx_tbl),
+ .rx_tbl = ipq8074_pcie_gen3_rx_tbl,
+ .rx_tbl_num = ARRAY_SIZE(ipq8074_pcie_gen3_rx_tbl),
+ .pcs_tbl = ipq8074_pcie_gen3_pcs_tbl,
+ .pcs_tbl_num = ARRAY_SIZE(ipq8074_pcie_gen3_pcs_tbl),
+ .clk_list = ipq8074_pciephy_clk_l,
+ .num_clks = ARRAY_SIZE(ipq8074_pciephy_clk_l),
+ .reset_list = ipq8074_pciephy_reset_l,
+ .num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
+ .vreg_list = NULL,
+ .num_vregs = 0,
+ .regs = qmp_v4_usb3phy_regs_layout,
+
+ .start_ctrl = SERDES_START | PCS_START,
+ .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
+
+ .has_phy_com_ctrl = false,
+ .has_lane_rst = false,
+ .has_pwrdn_delay = true,
+ .pwrdn_delay_min = 995, /* us */
+ .pwrdn_delay_max = 1005, /* us */
+};
+
static const struct qmp_phy_cfg sdm845_qmp_pciephy_cfg = {
.type = PHY_TYPE_PCIE,
.nlanes = 1,
@@ -2550,8 +2707,16 @@ static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np)

init.ops = &clk_fixed_rate_ops;

- /* controllers using QMP phys use 125MHz pipe clock interface */
- fixed->fixed_rate = 125000000;
+ /*
+ * controllers using QMP phys use 125MHz pipe clock interface unless
+ * other frequency is specified in dts
+ */
+ ret = of_property_read_u32(np, "clock-output-rate",
+ (u32 *)&fixed->fixed_rate);
+ if (ret)
+ fixed->fixed_rate = 125000000;
+
+ dev_info(qmp->dev, "fixed freq %lu\n", fixed->fixed_rate);
fixed->hw.init = &init;

ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
@@ -2719,6 +2884,9 @@ static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
.compatible = "qcom,ipq8074-qmp-pcie-phy",
.data = &ipq8074_pciephy_cfg,
}, {
+ .compatible = "qcom,ipq8074-qmp-pcie-gen3-phy",
+ .data = &ipq8074_pciephy_gen3_cfg,
+ }, {
.compatible = "qcom,sc7180-qmp-usb3-phy",
.data = &sc7180_usb3phy_cfg,
}, {
--
2.7.4

2020-07-05 09:19:23

by Sivaprakash Murugesan

[permalink] [raw]
Subject: [PATCH 9/9] arm64: dts: ipq8074: Fixup pcie dts nodes

ipq8074 pcie nodes missing several properties which is needed to make
them work add these properties.

Co-developed-by: Selvam Sathappan Periakaruppan <[email protected]>
Signed-off-by: Selvam Sathappan Periakaruppan <[email protected]>
Signed-off-by: Sivaprakash Murugesan <[email protected]>
---
arch/arm64/boot/dts/qcom/ipq8074-hk01.dts | 8 +--
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 109 ++++++++++++++++++++----------
2 files changed, 78 insertions(+), 39 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts b/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
index 6754cb0638f4..dfb8ad73f134 100644
--- a/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
+++ b/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
@@ -52,19 +52,19 @@

&pcie0 {
status = "ok";
- perst-gpio = <&tlmm 61 0x1>;
+ perst-gpio = <&tlmm 58 0x1>;
};

&pcie1 {
status = "ok";
- perst-gpio = <&tlmm 58 0x1>;
+ perst-gpio = <&tlmm 61 0x1>;
};

-&pcie_phy0 {
+&qmp_pcie_phy0 {
status = "ok";
};

-&pcie_phy1 {
+&qmp_pcie_phy1 {
status = "ok";
};

diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
index 5303821300b4..5bb58b70199e 100644
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -82,34 +82,66 @@
ranges = <0 0 0 0xffffffff>;
compatible = "simple-bus";

- pcie_phy0: phy@86000 {
- compatible = "qcom,ipq8074-qmp-pcie-phy";
- reg = <0x00086000 0x1000>;
- #phy-cells = <0>;
- clocks = <&gcc GCC_PCIE0_PIPE_CLK>;
- clock-names = "pipe_clk";
- clock-output-names = "pcie20_phy0_pipe_clk";
+ qmp_pcie_phy0: phy@84000 {
+ compatible = "qcom,ipq8074-qmp-pcie-gen3-phy";
+ reg = <0x00084000 0x1bc>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ clocks = <&gcc GCC_PCIE0_AUX_CLK>,
+ <&gcc GCC_PCIE0_AHB_CLK>;
+ clock-names = "aux", "cfg_ahb";

resets = <&gcc GCC_PCIE0_PHY_BCR>,
- <&gcc GCC_PCIE0PHY_PHY_BCR>;
+ <&gcc GCC_PCIE0PHY_PHY_BCR>;
reset-names = "phy",
"common";
+
status = "disabled";
+ pcie_phy0: lane@84200 {
+ reg = <0x84200 0x16c>, /* Serdes Tx */
+ <0x84400 0x200>, /* Serdes Rx */
+ <0x84800 0x4f4>; /* PCS: Lane0, COM, PCIE */
+ #phy-cells = <0>;
+
+ clocks = <&gcc GCC_PCIE0_PIPE_CLK>;
+ clock-names = "pipe0";
+ clock-output-names = "gcc_pcie0_pipe_clk_src";
+ clock-output-rate = <250000000>;
+ #clock-cells = <0>;
+ };
};

- pcie_phy1: phy@8e000 {
+ qmp_pcie_phy1: phy@8e000 {
compatible = "qcom,ipq8074-qmp-pcie-phy";
- reg = <0x0008e000 0x1000>;
- #phy-cells = <0>;
- clocks = <&gcc GCC_PCIE1_PIPE_CLK>;
- clock-names = "pipe_clk";
- clock-output-names = "pcie20_phy1_pipe_clk";
+ reg = <0x8e000 0x1c4>; /* Serdes PLL */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ clocks = <&gcc GCC_PCIE1_AUX_CLK>,
+ <&gcc GCC_PCIE1_AHB_CLK>;
+ clock-names = "aux", "cfg_ahb";

resets = <&gcc GCC_PCIE1_PHY_BCR>,
- <&gcc GCC_PCIE1PHY_PHY_BCR>;
+ <&gcc GCC_PCIE1PHY_PHY_BCR>;
reset-names = "phy",
"common";
+
status = "disabled";
+ pcie_phy1: lane@8e200 {
+ reg = <0x8e200 0x130>, /* Serdes Tx */
+ <0x8e400 0x200>, /* Serdes Rx */
+ <0x8e800 0x1f8>; /* PCS */
+ #phy-cells = <0>;
+
+ clocks = <&gcc GCC_PCIE1_PIPE_CLK>;
+ clock-names = "pipe0";
+ clock-output-names = "gcc_pcie1_pipe_clk_src";
+ clock-output-rate = <125000000>;
+ #clock-cells = <0>;
+ };
};

tlmm: pinctrl@1000000 {
@@ -370,10 +402,10 @@

pcie1: pci@10000000 {
compatible = "qcom,pcie-ipq8074";
- reg = <0x10000000 0xf1d
- 0x10000f20 0xa8
- 0x00088000 0x2000
- 0x10100000 0x1000>;
+ reg = <0x10000000 0xf1d>,
+ <0x10000f20 0xa8>,
+ <0x00088000 0x2000>,
+ <0x10100000 0x1000>;
reg-names = "dbi", "elbi", "parf", "config";
device_type = "pci";
linux,pci-domain = <1>;
@@ -386,9 +418,9 @@
phy-names = "pciephy";

ranges = <0x81000000 0 0x10200000 0x10200000
- 0 0x100000 /* downstream I/O */
- 0x82000000 0 0x10300000 0x10300000
- 0 0xd00000>; /* non-prefetchable memory */
+ 0 0x100000>, /* downstream I/O */
+ <0x82000000 0 0x10220000 0x10220000
+ 0 0xfde0000>; /* non-prefetchable memory */

interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "msi";
@@ -431,12 +463,13 @@
};

pcie0: pci@20000000 {
- compatible = "qcom,pcie-ipq8074";
- reg = <0x20000000 0xf1d
- 0x20000f20 0xa8
- 0x00080000 0x2000
- 0x20100000 0x1000>;
- reg-names = "dbi", "elbi", "parf", "config";
+ compatible = "qcom,pcie-ipq8074-gen3";
+ reg = <0x20000000 0xf1d>,
+ <0x20000f20 0xa8>,
+ <0x20001000 0x1000>,
+ <0x00080000 0x4000>,
+ <0x20100000 0x1000>;
+ reg-names = "dbi", "elbi", "atu", "parf", "config";
device_type = "pci";
linux,pci-domain = <0>;
bus-range = <0x00 0xff>;
@@ -448,9 +481,9 @@
phy-names = "pciephy";

ranges = <0x81000000 0 0x20200000 0x20200000
- 0 0x100000 /* downstream I/O */
- 0x82000000 0 0x20300000 0x20300000
- 0 0xd00000>; /* non-prefetchable memory */
+ 0 0x100000>, /* downstream I/O */
+ <0x82000000 0 0x20220000 0x20220000
+ 0 0xfde0000>; /* non-prefetchable memory */

interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "msi";
@@ -469,27 +502,33 @@
<&gcc GCC_PCIE0_AXI_M_CLK>,
<&gcc GCC_PCIE0_AXI_S_CLK>,
<&gcc GCC_PCIE0_AHB_CLK>,
- <&gcc GCC_PCIE0_AUX_CLK>;
+ <&gcc GCC_PCIE0_AUX_CLK>,
+ <&gcc GCC_PCIE0_AXI_S_BRIDGE_CLK>,
+ <&gcc GCC_PCIE0_RCHNG_CLK>;

clock-names = "iface",
"axi_m",
"axi_s",
"ahb",
- "aux";
+ "aux",
+ "axi_bridge",
+ "rchng";
resets = <&gcc GCC_PCIE0_PIPE_ARES>,
<&gcc GCC_PCIE0_SLEEP_ARES>,
<&gcc GCC_PCIE0_CORE_STICKY_ARES>,
<&gcc GCC_PCIE0_AXI_MASTER_ARES>,
<&gcc GCC_PCIE0_AXI_SLAVE_ARES>,
<&gcc GCC_PCIE0_AHB_ARES>,
- <&gcc GCC_PCIE0_AXI_MASTER_STICKY_ARES>;
+ <&gcc GCC_PCIE0_AXI_MASTER_STICKY_ARES>,
+ <&gcc GCC_PCIE0_AXI_SLAVE_STICKY_ARES>;
reset-names = "pipe",
"sleep",
"sticky",
"axi_m",
"axi_s",
"ahb",
- "axi_m_sticky";
+ "axi_m_sticky",
+ "axi_s_sticky";
status = "disabled";
};
};
--
2.7.4

2020-07-05 09:20:16

by Sivaprakash Murugesan

[permalink] [raw]
Subject: [PATCH 1/9] dt-bindings: pci: Add ipq8074 gen3 pci compatible

ipq8074 has two PCIe ports while the support for gen2 pcie port is
already available add the support for gen3 binding.

Co-developed-by: Selvam Sathappan Periakaruppan <[email protected]>
Signed-off-by: Selvam Sathappan Periakaruppan <[email protected]>
Signed-off-by: Sivaprakash Murugesan <[email protected]>
---
.../devicetree/bindings/pci/qcom,pcie.yaml | 47 ++++++++++++++++++++++
1 file changed, 47 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml
index b119ce4711b4..b5ec45df735e 100644
--- a/Documentation/devicetree/bindings/pci/qcom,pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml
@@ -22,6 +22,7 @@ properties:
- qcom,pcie-ipq4019
- qcom,pcie-ipq8064
- qcom,pcie-ipq8074
+ - qcom,pcie-ipq8074-gen3
- qcom,pcie-msm8996
- qcom,pcie-qcs404
- qcom,pcie-sdm845
@@ -330,6 +331,52 @@ allOf:
compatible:
contains:
enum:
+ - qcom,pcie-ipq8074-gen3
+ then:
+ properties:
+ clocks:
+ items:
+ - description: sys noc interface clock
+ - description: AXI master clock
+ - description: AXI slave clock
+ - description: AHB clock
+ - description: Auxilary clock
+ - description: AXI slave bridge clock
+ - description: PCIe rchng clock
+ clock-names:
+ items:
+ - const: iface
+ - const: axi_m
+ - const: axi_s
+ - const: ahb
+ - const: aux
+ - const: axi_bridge
+ - const: rchng
+ resets:
+ items:
+ - description: PIPE reset
+ - description: PCIe sleep reset
+ - description: PCIe sticky reset
+ - description: AXI master reset
+ - description: AXI slave reset
+ - description: AHB reset
+ - description: AXI master sticky reset
+ - description: AXI Slave sticky reset
+ reset-names:
+ items:
+ - const: pipe
+ - const: sleep
+ - const: sticky
+ - const: axi_m
+ - const: axi_s
+ - const: ahb
+ - const: axi_m_sticky
+ - const: axi_s_sticky
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
- qcom,pcie-msm8996
then:
properties:
--
2.7.4

2020-07-05 09:20:41

by Sivaprakash Murugesan

[permalink] [raw]
Subject: [PATCH 7/9] pci: dwc: qcom: do phy power on before pcie init

Commit cc1e06f033af ("phy: qcom: qmp: Use power_on/off ops for PCIe")
changed phy ops from init/deinit to power on/off, due to this phy enable
is getting called after pcie init.

On some platforms like ipq8074 phy should be inited before accessing the
pcie register space, otherwise the system would hang.

So move phy_power_on API before pcie init API.

Fixes: commit cc1e06f033af ("phy: qcom: qmp: Use power_on/off ops for PCIe")
Co-developed-by: Selvam Sathappan Periakaruppan <[email protected]>
Signed-off-by: Selvam Sathappan Periakaruppan <[email protected]>
Signed-off-by: Sivaprakash Murugesan <[email protected]>
---
drivers/pci/controller/dwc/pcie-qcom.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index 138e1a2d21cc..aa52a2124760 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1222,18 +1222,18 @@ static int qcom_pcie_host_init(struct pcie_port *pp)

qcom_ep_reset_assert(pcie);

- ret = pcie->ops->init(pcie);
+ ret = phy_power_on(pcie->phy);
if (ret)
return ret;

- ret = phy_power_on(pcie->phy);
+ ret = pcie->ops->init(pcie);
if (ret)
- goto err_deinit;
+ goto err_disable_phy;

if (pcie->ops->post_init) {
ret = pcie->ops->post_init(pcie);
if (ret)
- goto err_disable_phy;
+ goto err_deinit;
}

dw_pcie_setup_rc(pp);
@@ -1252,10 +1252,10 @@ static int qcom_pcie_host_init(struct pcie_port *pp)
qcom_ep_reset_assert(pcie);
if (pcie->ops->post_deinit)
pcie->ops->post_deinit(pcie);
-err_disable_phy:
- phy_power_off(pcie->phy);
err_deinit:
pcie->ops->deinit(pcie);
+err_disable_phy:
+ phy_power_off(pcie->phy);

return ret;
}
--
2.7.4

2020-07-05 09:23:23

by Sivaprakash Murugesan

[permalink] [raw]
Subject: [PATCH 3/9] clk: qcom: ipq8074: Add missing bindings for pcie

Add missing clock bindings for pcie port0 of ipq8074.

Co-developed-by: Selvam Sathappan Periakaruppan <[email protected]>
Signed-off-by: Selvam Sathappan Periakaruppan <[email protected]>
Signed-off-by: Sivaprakash Murugesan <[email protected]>
---
include/dt-bindings/clock/qcom,gcc-ipq8074.h | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/include/dt-bindings/clock/qcom,gcc-ipq8074.h b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
index 4de4811a3540..e3e018565add 100644
--- a/include/dt-bindings/clock/qcom,gcc-ipq8074.h
+++ b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
@@ -362,5 +362,9 @@
#define GCC_PCIE1_AXI_SLAVE_ARES 128
#define GCC_PCIE1_AHB_ARES 129
#define GCC_PCIE1_AXI_MASTER_STICKY_ARES 130
+#define GCC_PCIE0_AXI_SLAVE_STICKY_ARES 131
+#define GCC_PCIE0_AXI_S_BRIDGE_CLK 132
+#define GCC_PCIE0_RCHNG_CLK_SRC 133
+#define GCC_PCIE0_RCHNG_CLK 134

#endif
--
2.7.4

2020-07-06 23:50:22

by Bjorn Helgaas

[permalink] [raw]
Subject: Re: [PATCH 0/9] Add PCIe support for IPQ8074

On Sun, Jul 05, 2020 at 02:47:51PM +0530, Sivaprakash Murugesan wrote:
> IPQ8074 has two PCIe ports both are based on synopsis designware PCIe
> controller. while it was assumed that PCIe support for IPQ8074 was already
> available. PCIe was not functional until now.
>
> This patch series adds support for PCIe ports on IPQ8074.
>
> First PCIe port is of gen2 synposis version is 2_3_2 which has already been
> enabled. But it had some problems on phy init and needed dt updates.
>
> Second PCIe port is gen3 synopsis version is 2_9_0. This series adds
> support for this PCIe port while fixing dt nodes.
>
> Patch 1 on this series depends on qcom pcie bindings patch
> https://lkml.org/lkml/2020/6/24/162
>
> Sivaprakash Murugesan (9):
> dt-bindings: pci: Add ipq8074 gen3 pci compatible
> dt-bindings: phy: qcom,qmp: Add dt-binding for ipq8074 gen3 pcie phy
> clk: qcom: ipq8074: Add missing bindings for pcie
> clk: qcom: ipq8074: Add missing clocks for pcie
> phy: qcom-qmp: use correct values for ipq8074 gen2 pcie phy init
> phy: qcom-qmp: Add compatible for ipq8074 pcie gen3 qmp phy
> pci: dwc: qcom: do phy power on before pcie init
> pci: qcom: Add support for ipq8074 pci controller
> arm64: dts: ipq8074: Fixup pcie dts nodes

No comment on the patches themselves, but please update the subject
lines so they follow the conventions:

dt-bindings: PCI: qcom: Add ipq8074 PCIe Gen3 support
dt-bindings: phy: qcom,qmp: Add ipq8074 PCIe Gen3 phy
clk: qcom: ipq8074: Add missing bindings for PCIe
clk: qcom: ipq8074: Add missing clocks for PCIe
phy: qcom-qmp: Use correct values for ipq8074 PCIe Gen2 PHY init
PCI: qcom: Do PHY power on before PCIe init
PCI: qcom: Add ipq8074 PCIe controller support
arm64: dts: ipq8074: Fixup PCIe DTS nodes

Also fix the same things in the commit logs, e.g., consistently use
"PCIe" instead of "pcie", "Gen2" instead of "gen2", etc. For example:

ipq8074 has two PCIe ports while the support for gen2 pcie port ...

What's the point of using "PCIe" for the first and "pcie" for the
second?

You can learn all this by using "git log" and "git log --online".

> .../devicetree/bindings/pci/qcom,pcie.yaml | 47 ++++++
> .../devicetree/bindings/phy/qcom,qmp-phy.yaml | 1 +
> arch/arm64/boot/dts/qcom/ipq8074-hk01.dts | 8 +-
> arch/arm64/boot/dts/qcom/ipq8074.dtsi | 109 ++++++++----
> drivers/clk/qcom/gcc-ipq8074.c | 60 +++++++
> drivers/pci/controller/dwc/pcie-qcom.c | 187 +++++++++++++++++++-
> drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h | 132 +++++++++++++++
> drivers/phy/qualcomm/phy-qcom-qmp.c | 188 ++++++++++++++++++++-
> drivers/phy/qualcomm/phy-qcom-qmp.h | 2 +
> include/dt-bindings/clock/qcom,gcc-ipq8074.h | 4 +
> 10 files changed, 683 insertions(+), 55 deletions(-)
> create mode 100644 drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h
>
> --
> 2.7.4
>

2020-07-11 16:13:25

by Stephen Boyd

[permalink] [raw]
Subject: Re: [PATCH 3/9] clk: qcom: ipq8074: Add missing bindings for pcie

Quoting Sivaprakash Murugesan (2020-07-05 02:17:54)
> Add missing clock bindings for pcie port0 of ipq8074.
>
> Co-developed-by: Selvam Sathappan Periakaruppan <[email protected]>
> Signed-off-by: Selvam Sathappan Periakaruppan <[email protected]>
> Signed-off-by: Sivaprakash Murugesan <[email protected]>
> ---

Applied to clk-next

2020-07-13 05:56:45

by Vinod Koul

[permalink] [raw]
Subject: Re: [PATCH 5/9] phy: qcom-qmp: use correct values for ipq8074 gen2 pcie phy init

On 05-07-20, 14:47, Sivaprakash Murugesan wrote:
> There were some problem in ipq8074 gen2 pcie phy init sequence, fix

Can you please describe these problems, it would help review to
understand the issues and also for future reference to you

> these to make gen2 pcie port on ipq8074 to work.
>
> Fixes: eef243d04b2b6 ("phy: qcom-qmp: Add support for IPQ8074")
>
> Cc: [email protected]
> Co-developed-by: Selvam Sathappan Periakaruppan <[email protected]>
> Signed-off-by: Selvam Sathappan Periakaruppan <[email protected]>
> Signed-off-by: Sivaprakash Murugesan <[email protected]>
> ---
> drivers/phy/qualcomm/phy-qcom-qmp.c | 16 +++++++++-------
> drivers/phy/qualcomm/phy-qcom-qmp.h | 2 ++
> 2 files changed, 11 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
> index e91040af3394..ba277136f52b 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
> @@ -504,8 +504,8 @@ static const struct qmp_phy_init_tbl ipq8074_pcie_serdes_tbl[] = {
> QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0xf),
> QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x1),
> QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x0),
> - QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0x1f),
> - QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
> + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
> + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x1f),
> QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x6),
> QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0xf),
> QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x0),
> @@ -531,7 +531,6 @@ static const struct qmp_phy_init_tbl ipq8074_pcie_serdes_tbl[] = {
> QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x0),
> QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
> QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x1),
> - QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0xa),
> QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x1),
> QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
> QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x1),
> @@ -540,7 +539,6 @@ static const struct qmp_phy_init_tbl ipq8074_pcie_serdes_tbl[] = {
> QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x2f),
> QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x19),
> QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV, 0x19),
> - QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x7),
> };
>
> static const struct qmp_phy_init_tbl ipq8074_pcie_tx_tbl[] = {
> @@ -548,6 +546,8 @@ static const struct qmp_phy_init_tbl ipq8074_pcie_tx_tbl[] = {
> QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x6),
> QMP_PHY_INIT_CFG(QSERDES_TX_RES_CODE_LANE_OFFSET, 0x2),
> QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2, 0x12),
> + QMP_PHY_INIT_CFG(QSERDES_TX_EMP_POST1_LVL, 0x36),
> + QMP_PHY_INIT_CFG(QSERDES_TX_SLEW_CNTL, 0x0a),
> };
>
> static const struct qmp_phy_init_tbl ipq8074_pcie_rx_tbl[] = {
> @@ -558,7 +558,6 @@ static const struct qmp_phy_init_tbl ipq8074_pcie_rx_tbl[] = {
> QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xdb),
> QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
> QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x4),
> - QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN_HALF, 0x4),
> };
>
> static const struct qmp_phy_init_tbl ipq8074_pcie_pcs_tbl[] = {
> @@ -1673,6 +1672,9 @@ static const struct qmp_phy_cfg msm8996_usb3phy_cfg = {
> .pwrdn_ctrl = SW_PWRDN,
> };
>
> +static const char * const ipq8074_pciephy_clk_l[] = {
> + "aux", "cfg_ahb",
> +};
> /* list of resets */
> static const char * const ipq8074_pciephy_reset_l[] = {
> "phy", "common",
> @@ -1690,8 +1692,8 @@ static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
> .rx_tbl_num = ARRAY_SIZE(ipq8074_pcie_rx_tbl),
> .pcs_tbl = ipq8074_pcie_pcs_tbl,
> .pcs_tbl_num = ARRAY_SIZE(ipq8074_pcie_pcs_tbl),
> - .clk_list = NULL,
> - .num_clks = 0,
> + .clk_list = ipq8074_pciephy_clk_l,
> + .num_clks = ARRAY_SIZE(ipq8074_pciephy_clk_l),

I see patch is modifying some register values and then adding clks, in
the absence of proper patch description it is extremely hard to
understand what is going on..

> .reset_list = ipq8074_pciephy_reset_l,
> .num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
> .vreg_list = NULL,
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h
> index 6d017a0c0c8d..832b3d098403 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp.h
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
> @@ -77,6 +77,8 @@
> #define QSERDES_COM_CORECLK_DIV_MODE1 0x1bc
>
> /* Only for QMP V2 PHY - TX registers */
> +#define QSERDES_TX_EMP_POST1_LVL 0x018
> +#define QSERDES_TX_SLEW_CNTL 0x040
> #define QSERDES_TX_RES_CODE_LANE_OFFSET 0x054
> #define QSERDES_TX_DEBUG_BUS_SEL 0x064
> #define QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN 0x068
> --
> 2.7.4

--
~Vinod

2020-07-13 06:05:00

by Vinod Koul

[permalink] [raw]
Subject: Re: [PATCH 6/9] phy: qcom-qmp: Add compatible for ipq8074 pcie gen3 qmp phy

On 05-07-20, 14:47, Sivaprakash Murugesan wrote:
> ipq8074 has two pcie ports, one gen2 and one gen3 ports. with phy
> support already available for gen2 pcie ports add support for pcie gen3
> port phy.
>
> Co-developed-by: Selvam Sathappan Periakaruppan <[email protected]>
> Signed-off-by: Selvam Sathappan Periakaruppan <[email protected]>
> Signed-off-by: Sivaprakash Murugesan <[email protected]>
> ---
> drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h | 137 ++++++++++++++++++++++++
> drivers/phy/qualcomm/phy-qcom-qmp.c | 172 +++++++++++++++++++++++++++++-
> 2 files changed, 307 insertions(+), 2 deletions(-)
> create mode 100644 drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h b/drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h
> new file mode 100644
> index 000000000000..bb567673d9b5
> --- /dev/null
> +++ b/drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h
> @@ -0,0 +1,137 @@
> +/* SPDX-License-Identifier: GPL-2.0*

Trailing * at the end, it would make sense to split the spdx and
copyright parts to two single lines

> @@ -2550,8 +2707,16 @@ static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np)
>
> init.ops = &clk_fixed_rate_ops;
>
> - /* controllers using QMP phys use 125MHz pipe clock interface */
> - fixed->fixed_rate = 125000000;
> + /*
> + * controllers using QMP phys use 125MHz pipe clock interface unless
> + * other frequency is specified in dts
> + */
> + ret = of_property_read_u32(np, "clock-output-rate",
> + (u32 *)&fixed->fixed_rate);

is this cast required?

> + if (ret)
> + fixed->fixed_rate = 125000000;
> +
> + dev_info(qmp->dev, "fixed freq %lu\n", fixed->fixed_rate);

debug?

--
~Vinod

2020-07-15 21:51:04

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH 1/9] dt-bindings: pci: Add ipq8074 gen3 pci compatible

On Sun, 05 Jul 2020 14:47:52 +0530, Sivaprakash Murugesan wrote:
> ipq8074 has two PCIe ports while the support for gen2 pcie port is
> already available add the support for gen3 binding.
>
> Co-developed-by: Selvam Sathappan Periakaruppan <[email protected]>
> Signed-off-by: Selvam Sathappan Periakaruppan <[email protected]>
> Signed-off-by: Sivaprakash Murugesan <[email protected]>
> ---
> .../devicetree/bindings/pci/qcom,pcie.yaml | 47 ++++++++++++++++++++++
> 1 file changed, 47 insertions(+)
>

Reviewed-by: Rob Herring <[email protected]>

2020-07-29 06:47:46

by Sivaprakash Murugesan

[permalink] [raw]
Subject: Re: [PATCH 5/9] phy: qcom-qmp: use correct values for ipq8074 gen2 pcie phy init


On 7/13/2020 11:25 AM, Vinod Koul wrote:
> On 05-07-20, 14:47, Sivaprakash Murugesan wrote:
>> There were some problem in ipq8074 gen2 pcie phy init sequence, fix
> Can you please describe these problems, it would help review to
> understand the issues and also for future reference to you

Hi Vinod,

As you mentioned we are updating few register values

and also adding clocks and resets.

the register values are given by the Hardware team and there

is some fine tuning values are provided by Hardware team for the

issues we faced downstream.

Also, few register values are typos for example QSERDES_RX_SIGDET_CNTRL

is a rx register it was wrongly in serdes table.

I will try to mention these details in next patch.

2020-07-29 07:48:17

by Sivaprakash Murugesan

[permalink] [raw]
Subject: Re: [PATCH 6/9] phy: qcom-qmp: Add compatible for ipq8074 pcie gen3 qmp phy

Hi Vinod,

On 7/13/2020 11:34 AM, Vinod Koul wrote:
> On 05-07-20, 14:47, Sivaprakash Murugesan wrote:
>> ipq8074 has two pcie ports, one gen2 and one gen3 ports. with phy
>> support already available for gen2 pcie ports add support for pcie gen3
>> port phy.
>>
>> Co-developed-by: Selvam Sathappan Periakaruppan <[email protected]>
>> Signed-off-by: Selvam Sathappan Periakaruppan <[email protected]>
>> Signed-off-by: Sivaprakash Murugesan <[email protected]>
>> ---
>> drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h | 137 ++++++++++++++++++++++++
>> drivers/phy/qualcomm/phy-qcom-qmp.c | 172 +++++++++++++++++++++++++++++-
>> 2 files changed, 307 insertions(+), 2 deletions(-)
>> create mode 100644 drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h b/drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h
>> new file mode 100644
>> index 000000000000..bb567673d9b5
>> --- /dev/null
>> +++ b/drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h
>> @@ -0,0 +1,137 @@
>> +/* SPDX-License-Identifier: GPL-2.0*
> Trailing * at the end, it would make sense to split the spdx and
> copyright parts to two single lines
ok
>
>> @@ -2550,8 +2707,16 @@ static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np)
>>
>> init.ops = &clk_fixed_rate_ops;
>>
>> - /* controllers using QMP phys use 125MHz pipe clock interface */
>> - fixed->fixed_rate = 125000000;
>> + /*
>> + * controllers using QMP phys use 125MHz pipe clock interface unless
>> + * other frequency is specified in dts
>> + */
>> + ret = of_property_read_u32(np, "clock-output-rate",
>> + (u32 *)&fixed->fixed_rate);
> is this cast required?

without this getting the following error.

./include/linux/of.h:1209:19: note: expected 'u32 * {aka unsigned int
*}' but argument is of type 'long unsigned int *'

>
>> + if (ret)
>> + fixed->fixed_rate = 125000000;
>> +
>> + dev_info(qmp->dev, "fixed freq %lu\n", fixed->fixed_rate);
> debug?
will remove in next patch.

2020-08-03 11:04:21

by Vinod Koul

[permalink] [raw]
Subject: Re: [PATCH 5/9] phy: qcom-qmp: use correct values for ipq8074 gen2 pcie phy init

Hi Sivaprakash,

On 29-07-20, 12:15, Sivaprakash Murugesan wrote:
>
> On 7/13/2020 11:25 AM, Vinod Koul wrote:
> > On 05-07-20, 14:47, Sivaprakash Murugesan wrote:
> > > There were some problem in ipq8074 gen2 pcie phy init sequence, fix
> > Can you please describe these problems, it would help review to
> > understand the issues and also for future reference to you
>
> Hi Vinod,
>
> As you mentioned we are updating few register values
>
> and also adding clocks and resets.
>
> the register values are given by the Hardware team and there
>
> is some fine tuning values are provided by Hardware team for the
>
> issues we faced downstream.
>
> Also, few register values are typos for example QSERDES_RX_SIGDET_CNTRL
>
> is a rx register it was wrongly in serdes table.
>
> I will try to mention these details in next patch.

The right thing to do would be a change per patch explaining the reason.
For example, fixing typos in QSERDES_RX_SIGDET_CNTRL, then another to
update tuning values based on hw recommendations. Clocks and reset
should be different patch

This helps us review each change for what it does and helps you down the
line to figure why a line of code was changed

HTH

--
~Vinod