]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
PCI: qcom: Add equalization settings for 16.0 GT/s
authorShashank Babu Chinta Venkata <quic_schintav@quicinc.com>
Wed, 11 Sep 2024 15:26:28 +0000 (20:56 +0530)
committerKrzysztof Wilczyński <kwilczynski@kernel.org>
Fri, 13 Sep 2024 14:44:57 +0000 (14:44 +0000)
During high data transmission rates such as 16.0 GT/s, there is an
increased risk of signal loss due to poor channel quality and
interference. This can impact receiver's ability to capture signals
accurately.

Hence, as signal compensation is achieved through appropriate lane
equalization, apply lane equalization settings at both transmitter
and receiver which results in an increase in the PCIe signal strength.

While at it, modify the pcie-tegra194 driver to make use of the
common GEN3_EQ_CONTROL_OFF definitions in pcie-designware.h.

Link: https://lore.kernel.org/linux-pci/20240911-pci-qcom-gen4-stability-v7-3-743f5c1fd027@linaro.org
Tested-by: Johan Hovold <johan+linaro@kernel.org>
Signed-off-by: Shashank Babu Chinta Venkata <quic_schintav@quicinc.com>
[mani: dropped the code refactoring and minor changes]
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
[kwilczynski: commit log]
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
MAINTAINERS
drivers/pci/controller/dwc/Kconfig
drivers/pci/controller/dwc/Makefile
drivers/pci/controller/dwc/pcie-designware.h
drivers/pci/controller/dwc/pcie-qcom-common.c [new file with mode: 0644]
drivers/pci/controller/dwc/pcie-qcom-common.h [new file with mode: 0644]
drivers/pci/controller/dwc/pcie-qcom-ep.c
drivers/pci/controller/dwc/pcie-qcom.c
drivers/pci/controller/dwc/pcie-tegra194.c

index 42decde3832066e43a460a83b0634e4d9af0c797..90a88d1041da074b62bd56fd014c567878ff17fe 100644 (file)
@@ -2728,7 +2728,7 @@ F:        drivers/iommu/msm*
 F:     drivers/mfd/ssbi.c
 F:     drivers/mmc/host/mmci_qcom*
 F:     drivers/mmc/host/sdhci-msm.c
-F:     drivers/pci/controller/dwc/pcie-qcom.c
+F:     drivers/pci/controller/dwc/pcie-qcom*
 F:     drivers/phy/qualcomm/
 F:     drivers/power/*/msm*
 F:     drivers/reset/reset-qcom-*
@@ -17754,6 +17754,7 @@ M:      Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
 L:     linux-pci@vger.kernel.org
 L:     linux-arm-msm@vger.kernel.org
 S:     Maintained
+F:     drivers/pci/controller/dwc/pcie-qcom-common.c
 F:     drivers/pci/controller/dwc/pcie-qcom.c
 
 PCIE DRIVER FOR ROCKCHIP
@@ -17790,6 +17791,7 @@ L:      linux-pci@vger.kernel.org
 L:     linux-arm-msm@vger.kernel.org
 S:     Maintained
 F:     Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml
+F:     drivers/pci/controller/dwc/pcie-qcom-common.c
 F:     drivers/pci/controller/dwc/pcie-qcom-ep.c
 
 PCMCIA SUBSYSTEM
index 4c38181acffab40965cd9bc1cf67477bce1e7959..b6d6778b0698b2ab22ef69f6c8d8cd5619ede41f 100644 (file)
@@ -265,12 +265,16 @@ config PCIE_DW_PLAT_EP
          order to enable device-specific features PCI_DW_PLAT_EP must be
          selected.
 
+config PCIE_QCOM_COMMON
+       bool
+
 config PCIE_QCOM
        bool "Qualcomm PCIe controller (host mode)"
        depends on OF && (ARCH_QCOM || COMPILE_TEST)
        depends on PCI_MSI
        select PCIE_DW_HOST
        select CRC8
+       select PCIE_QCOM_COMMON
        help
          Say Y here to enable PCIe controller support on Qualcomm SoCs. The
          PCIe controller uses the DesignWare core plus Qualcomm-specific
@@ -281,6 +285,7 @@ config PCIE_QCOM_EP
        depends on OF && (ARCH_QCOM || COMPILE_TEST)
        depends on PCI_ENDPOINT
        select PCIE_DW_EP
+       select PCIE_QCOM_COMMON
        help
          Say Y here to enable support for the PCIe controllers on Qualcomm SoCs
          to work in endpoint mode. The PCIe controller uses the DesignWare core
index ec215b3d619163792dec752fbe9d7ae19d9072c8..a8308d9ea9861f633a89407321120f6f6857a428 100644 (file)
@@ -12,6 +12,7 @@ obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
 obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone.o
 obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
 obj-$(CONFIG_PCI_LAYERSCAPE_EP) += pci-layerscape-ep.o
+obj-$(CONFIG_PCIE_QCOM_COMMON) += pcie-qcom-common.o
 obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o
 obj-$(CONFIG_PCIE_QCOM_EP) += pcie-qcom-ep.o
 obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
index 1a1769244e833d8e08c2813ffd182452b7a298c9..67cc2677ab2e71a4a83908691311a60c4cbd10ad 100644 (file)
 #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE       BIT(16)
 #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT 24
 #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK  GENMASK(25, 24)
+#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_16_0GT        0x1
+
+#define GEN3_EQ_CONTROL_OFF                    0x8A8
+#define GEN3_EQ_CONTROL_OFF_FB_MODE            GENMASK(3, 0)
+#define GEN3_EQ_CONTROL_OFF_PHASE23_EXIT_MODE  BIT(4)
+#define GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC       GENMASK(23, 8)
+#define GEN3_EQ_CONTROL_OFF_FOM_INC_INITIAL_EVAL       BIT(24)
+
+#define GEN3_EQ_FB_MODE_DIR_CHANGE_OFF         0x8AC
+#define GEN3_EQ_FMDC_T_MIN_PHASE23             GENMASK(4, 0)
+#define GEN3_EQ_FMDC_N_EVALS                   GENMASK(9, 5)
+#define GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA      GENMASK(13, 10)
+#define GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA     GENMASK(17, 14)
 
 #define PCIE_PORT_MULTI_LANE_CTRL      0x8C0
 #define PORT_MLTI_UPCFG_SUPPORT                BIT(7)
diff --git a/drivers/pci/controller/dwc/pcie-qcom-common.c b/drivers/pci/controller/dwc/pcie-qcom-common.c
new file mode 100644 (file)
index 0000000..596a354
--- /dev/null
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/pci.h>
+
+#include "pcie-designware.h"
+#include "pcie-qcom-common.h"
+
+void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci)
+{
+       u32 reg;
+
+       /*
+        * GEN3_RELATED_OFF register is repurposed to apply equalization
+        * settings at various data transmission rates through registers namely
+        * GEN3_EQ_*. The RATE_SHADOW_SEL bit field of GEN3_RELATED_OFF
+        * determines the data rate for which these equalization settings are
+        * applied.
+        */
+       reg = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
+       reg &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
+       reg &= ~GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK;
+       reg |= FIELD_PREP(GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK,
+                         GEN3_RELATED_OFF_RATE_SHADOW_SEL_16_0GT);
+       dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, reg);
+
+       reg = dw_pcie_readl_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF);
+       reg &= ~(GEN3_EQ_FMDC_T_MIN_PHASE23 |
+               GEN3_EQ_FMDC_N_EVALS |
+               GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA |
+               GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA);
+       reg |= FIELD_PREP(GEN3_EQ_FMDC_T_MIN_PHASE23, 0x1) |
+               FIELD_PREP(GEN3_EQ_FMDC_N_EVALS, 0xd) |
+               FIELD_PREP(GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA, 0x5) |
+               FIELD_PREP(GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA, 0x5);
+       dw_pcie_writel_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF, reg);
+
+       reg = dw_pcie_readl_dbi(pci, GEN3_EQ_CONTROL_OFF);
+       reg &= ~(GEN3_EQ_CONTROL_OFF_FB_MODE |
+               GEN3_EQ_CONTROL_OFF_PHASE23_EXIT_MODE |
+               GEN3_EQ_CONTROL_OFF_FOM_INC_INITIAL_EVAL |
+               GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC);
+       dw_pcie_writel_dbi(pci, GEN3_EQ_CONTROL_OFF, reg);
+}
+EXPORT_SYMBOL_GPL(qcom_pcie_common_set_16gt_equalization);
diff --git a/drivers/pci/controller/dwc/pcie-qcom-common.h b/drivers/pci/controller/dwc/pcie-qcom-common.h
new file mode 100644 (file)
index 0000000..536387e
--- /dev/null
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _PCIE_QCOM_COMMON_H
+#define _PCIE_QCOM_COMMON_H
+
+struct dw_pcie;
+
+void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci);
+
+#endif
index 3c1b695638f3c32444ca04b1bd8897197bb5648f..310d52393392fa209d0cce2453505819c4d1e02b 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "../../pci.h"
 #include "pcie-designware.h"
+#include "pcie-qcom-common.h"
 
 /* PARF registers */
 #define PARF_SYS_CTRL                          0x00
@@ -486,6 +487,9 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
                goto err_disable_resources;
        }
 
+       if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT)
+               qcom_pcie_common_set_16gt_equalization(pci);
+
        /*
         * The physical address of the MMIO region which is exposed as the BAR
         * should be written to MHI BASE registers.
index 1923266acea89f7cc1d8273ffcf2a459573fc30e..1e84366ac0bb2a5b25048d496ac1a2af2e783324 100644 (file)
@@ -35,6 +35,7 @@
 
 #include "../../pci.h"
 #include "pcie-designware.h"
+#include "pcie-qcom-common.h"
 
 /* PARF registers */
 #define PARF_SYS_CTRL                          0x00
@@ -295,6 +296,9 @@ static int qcom_pcie_start_link(struct dw_pcie *pci)
 {
        struct qcom_pcie *pcie = to_qcom_pcie(pci);
 
+       if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT)
+               qcom_pcie_common_set_16gt_equalization(pci);
+
        /* Enable Link Training state machine */
        if (pcie->cfg->ops->ltssm_enable)
                pcie->cfg->ops->ltssm_enable(pcie);
index 4bf7b433417a3b8708949287d24ea299c61bbe45..6e03e14151d64687c47d46615c736d90beeee47b 100644 (file)
 #define N_FTS_VAL                                      52
 #define FTS_VAL                                                52
 
-#define GEN3_EQ_CONTROL_OFF                    0x8a8
-#define GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC_SHIFT 8
-#define GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC_MASK  GENMASK(23, 8)
-#define GEN3_EQ_CONTROL_OFF_FB_MODE_MASK       GENMASK(3, 0)
-
 #define PORT_LOGIC_AMBA_ERROR_RESPONSE_DEFAULT 0x8D0
 #define AMBA_ERROR_RESPONSE_CRS_SHIFT          3
 #define AMBA_ERROR_RESPONSE_CRS_MASK           GENMASK(1, 0)
@@ -861,9 +856,9 @@ static void config_gen3_gen4_eq_presets(struct tegra_pcie_dw *pcie)
        dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, val);
 
        val = dw_pcie_readl_dbi(pci, GEN3_EQ_CONTROL_OFF);
-       val &= ~GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC_MASK;
-       val |= (0x3ff << GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC_SHIFT);
-       val &= ~GEN3_EQ_CONTROL_OFF_FB_MODE_MASK;
+       val &= ~GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC;
+       val |= FIELD_PREP(GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC, 0x3ff);
+       val &= ~GEN3_EQ_CONTROL_OFF_FB_MODE;
        dw_pcie_writel_dbi(pci, GEN3_EQ_CONTROL_OFF, val);
 
        val = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
@@ -872,10 +867,10 @@ static void config_gen3_gen4_eq_presets(struct tegra_pcie_dw *pcie)
        dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, val);
 
        val = dw_pcie_readl_dbi(pci, GEN3_EQ_CONTROL_OFF);
-       val &= ~GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC_MASK;
-       val |= (pcie->of_data->gen4_preset_vec <<
-               GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC_SHIFT);
-       val &= ~GEN3_EQ_CONTROL_OFF_FB_MODE_MASK;
+       val &= ~GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC;
+       val |= FIELD_PREP(GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC,
+                         pcie->of_data->gen4_preset_vec);
+       val &= ~GEN3_EQ_CONTROL_OFF_FB_MODE;
        dw_pcie_writel_dbi(pci, GEN3_EQ_CONTROL_OFF, val);
 
        val = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);