Commit 37bf0f4e authored by Ziyue Zhang's avatar Ziyue Zhang Committed by Manivannan Sadhasivam
Browse files

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: 489f14be ("arm64: dts: qcom: sa8775p: Add pcie0 and pcie1 nodes")
Co-developed-by: default avatarQiang Yu <qiang.yu@oss.qualcomm.com>
Signed-off-by: default avatarQiang Yu <qiang.yu@oss.qualcomm.com>
Signed-off-by: default avatarZiyue Zhang <ziyue.zhang@oss.qualcomm.com>
[mani: wrapped the warning to fit 100 columns, used post-increment for loop]
Signed-off-by: default avatarManivannan Sadhasivam <mani@kernel.org>
Link: https://patch.msgid.link/20250904065225.1762793-2-ziyue.zhang@oss.qualcomm.com
parent 45df2293
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -123,7 +123,6 @@
#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)
+34 −24
Original line number Diff line number Diff line
@@ -8,9 +8,11 @@
#include "pcie-designware.h"
#include "pcie-qcom-common.h"

void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci)
void qcom_pcie_common_set_equalization(struct dw_pcie *pci)
{
	struct device *dev = pci->dev;
	u32 reg;
	u16 speed;

	/*
	 * GEN3_RELATED_OFF register is repurposed to apply equalization
@@ -19,11 +21,18 @@ void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci)
	 * determines the data rate for which these equalization settings are
	 * applied.
	 */

	for (speed = PCIE_SPEED_8_0GT; speed <= pcie_link_speed[pci->max_link_speed]; speed++) {
		if (speed > PCIE_SPEED_32_0GT) {
			dev_warn(dev, "Skipped equalization settings for unsupported data rate\n");
			break;
		}

		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);
			  speed - PCIE_SPEED_8_0GT);
		dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, reg);

		reg = dw_pcie_readl_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF);
@@ -44,7 +53,8 @@ void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci)
			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);
}
EXPORT_SYMBOL_GPL(qcom_pcie_common_set_equalization);

void qcom_pcie_common_set_16gt_lane_margining(struct dw_pcie *pci)
{
+1 −1
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@

struct dw_pcie;

void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci);
void qcom_pcie_common_set_equalization(struct dw_pcie *pci);
void qcom_pcie_common_set_16gt_lane_margining(struct dw_pcie *pci);

#endif
+3 −3
Original line number Diff line number Diff line
@@ -511,10 +511,10 @@ 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);
	qcom_pcie_common_set_equalization(pci);

	if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT)
		qcom_pcie_common_set_16gt_lane_margining(pci);
	}

	/*
	 * The physical address of the MMIO region which is exposed as the BAR
+3 −3
Original line number Diff line number Diff line
@@ -322,10 +322,10 @@ 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);
	qcom_pcie_common_set_equalization(pci);

	if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT)
		qcom_pcie_common_set_16gt_lane_margining(pci);
	}

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