Skip to content

Commit 37bf0f4

Browse files
Ziyue ZhangMani-Sadhasivam
authored andcommitted
PCI: qcom: Add equalization settings for 8.0 GT/s and 32.0 GT/s
Add lane equalization setting for 8.0 GT/s and 32.0 GT/s to enhance link stability and avoid AER Correctable Errors reported on some platforms (eg. SA8775P). 8.0 GT/s, 16.0 GT/s and 32.0 GT/s require the same equalization setting. This setting is programmed into a group of shadow registers, which can be switched to configure equalization for different speeds by writing 00b, 01b and 10b to `RATE_SHADOW_SEL`. Hence, program equalization registers in a loop using link speed as index, so that equalization setting can be programmed for 8.0 GT/s, 16.0 GT/s and 32.0 GT/s. Fixes: 489f14b ("arm64: dts: qcom: sa8775p: Add pcie0 and pcie1 nodes") Co-developed-by: Qiang Yu <qiang.yu@oss.qualcomm.com> Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com> Signed-off-by: Ziyue Zhang <ziyue.zhang@oss.qualcomm.com> [mani: wrapped the warning to fit 100 columns, used post-increment for loop] Signed-off-by: Manivannan Sadhasivam <mani@kernel.org> Link: https://patch.msgid.link/20250904065225.1762793-2-ziyue.zhang@oss.qualcomm.com
1 parent 45df229 commit 37bf0f4

5 files changed

Lines changed: 41 additions & 32 deletions

File tree

drivers/pci/controller/dwc/pcie-designware.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@
123123
#define GEN3_RELATED_OFF_GEN3_EQ_DISABLE BIT(16)
124124
#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT 24
125125
#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK GENMASK(25, 24)
126-
#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_16_0GT 0x1
127126

128127
#define GEN3_EQ_CONTROL_OFF 0x8A8
129128
#define GEN3_EQ_CONTROL_OFF_FB_MODE GENMASK(3, 0)

drivers/pci/controller/dwc/pcie-qcom-common.c

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
#include "pcie-designware.h"
99
#include "pcie-qcom-common.h"
1010

11-
void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci)
11+
void qcom_pcie_common_set_equalization(struct dw_pcie *pci)
1212
{
13+
struct device *dev = pci->dev;
1314
u32 reg;
15+
u16 speed;
1416

1517
/*
1618
* GEN3_RELATED_OFF register is repurposed to apply equalization
@@ -19,32 +21,40 @@ void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci)
1921
* determines the data rate for which these equalization settings are
2022
* applied.
2123
*/
22-
reg = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
23-
reg &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
24-
reg &= ~GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK;
25-
reg |= FIELD_PREP(GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK,
26-
GEN3_RELATED_OFF_RATE_SHADOW_SEL_16_0GT);
27-
dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, reg);
2824

29-
reg = dw_pcie_readl_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF);
30-
reg &= ~(GEN3_EQ_FMDC_T_MIN_PHASE23 |
31-
GEN3_EQ_FMDC_N_EVALS |
32-
GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA |
33-
GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA);
34-
reg |= FIELD_PREP(GEN3_EQ_FMDC_T_MIN_PHASE23, 0x1) |
35-
FIELD_PREP(GEN3_EQ_FMDC_N_EVALS, 0xd) |
36-
FIELD_PREP(GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA, 0x5) |
37-
FIELD_PREP(GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA, 0x5);
38-
dw_pcie_writel_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF, reg);
25+
for (speed = PCIE_SPEED_8_0GT; speed <= pcie_link_speed[pci->max_link_speed]; speed++) {
26+
if (speed > PCIE_SPEED_32_0GT) {
27+
dev_warn(dev, "Skipped equalization settings for unsupported data rate\n");
28+
break;
29+
}
3930

40-
reg = dw_pcie_readl_dbi(pci, GEN3_EQ_CONTROL_OFF);
41-
reg &= ~(GEN3_EQ_CONTROL_OFF_FB_MODE |
42-
GEN3_EQ_CONTROL_OFF_PHASE23_EXIT_MODE |
43-
GEN3_EQ_CONTROL_OFF_FOM_INC_INITIAL_EVAL |
44-
GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC);
45-
dw_pcie_writel_dbi(pci, GEN3_EQ_CONTROL_OFF, reg);
31+
reg = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
32+
reg &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
33+
reg &= ~GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK;
34+
reg |= FIELD_PREP(GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK,
35+
speed - PCIE_SPEED_8_0GT);
36+
dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, reg);
37+
38+
reg = dw_pcie_readl_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF);
39+
reg &= ~(GEN3_EQ_FMDC_T_MIN_PHASE23 |
40+
GEN3_EQ_FMDC_N_EVALS |
41+
GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA |
42+
GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA);
43+
reg |= FIELD_PREP(GEN3_EQ_FMDC_T_MIN_PHASE23, 0x1) |
44+
FIELD_PREP(GEN3_EQ_FMDC_N_EVALS, 0xd) |
45+
FIELD_PREP(GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA, 0x5) |
46+
FIELD_PREP(GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA, 0x5);
47+
dw_pcie_writel_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF, reg);
48+
49+
reg = dw_pcie_readl_dbi(pci, GEN3_EQ_CONTROL_OFF);
50+
reg &= ~(GEN3_EQ_CONTROL_OFF_FB_MODE |
51+
GEN3_EQ_CONTROL_OFF_PHASE23_EXIT_MODE |
52+
GEN3_EQ_CONTROL_OFF_FOM_INC_INITIAL_EVAL |
53+
GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC);
54+
dw_pcie_writel_dbi(pci, GEN3_EQ_CONTROL_OFF, reg);
55+
}
4656
}
47-
EXPORT_SYMBOL_GPL(qcom_pcie_common_set_16gt_equalization);
57+
EXPORT_SYMBOL_GPL(qcom_pcie_common_set_equalization);
4858

4959
void qcom_pcie_common_set_16gt_lane_margining(struct dw_pcie *pci)
5060
{

drivers/pci/controller/dwc/pcie-qcom-common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
struct dw_pcie;
1010

11-
void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci);
11+
void qcom_pcie_common_set_equalization(struct dw_pcie *pci);
1212
void qcom_pcie_common_set_16gt_lane_margining(struct dw_pcie *pci);
1313

1414
#endif

drivers/pci/controller/dwc/pcie-qcom-ep.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -511,10 +511,10 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
511511
goto err_disable_resources;
512512
}
513513

514-
if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT) {
515-
qcom_pcie_common_set_16gt_equalization(pci);
514+
qcom_pcie_common_set_equalization(pci);
515+
516+
if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT)
516517
qcom_pcie_common_set_16gt_lane_margining(pci);
517-
}
518518

519519
/*
520520
* The physical address of the MMIO region which is exposed as the BAR

drivers/pci/controller/dwc/pcie-qcom.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -322,10 +322,10 @@ static int qcom_pcie_start_link(struct dw_pcie *pci)
322322
{
323323
struct qcom_pcie *pcie = to_qcom_pcie(pci);
324324

325-
if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT) {
326-
qcom_pcie_common_set_16gt_equalization(pci);
325+
qcom_pcie_common_set_equalization(pci);
326+
327+
if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT)
327328
qcom_pcie_common_set_16gt_lane_margining(pci);
328-
}
329329

330330
/* Enable Link Training state machine */
331331
if (pcie->cfg->ops->ltssm_enable)

0 commit comments

Comments
 (0)