Commit d14bc28a authored by Shashank Babu Chinta Venkata's avatar Shashank Babu Chinta Venkata Committed by Krzysztof Wilczyński

PCI: qcom: Add RX lane margining settings for 16.0 GT/s

Add RX lane margining settings for 16.0 GT/s (GEN 4) data rate.

These settings improve link stability while operating at high date
rates and helps to improve signal quality.

Link: https://lore.kernel.org/linux-pci/20240911-pci-qcom-gen4-stability-v7-4-743f5c1fd027@linaro.orgTested-by: default avatarJohan Hovold <johan+linaro@kernel.org>
Signed-off-by: default avatarShashank Babu Chinta Venkata <quic_schintav@quicinc.com>
[mani: dropped the code refactoring and minor changes]
Signed-off-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
[kwilczynski: commit log]
Signed-off-by: default avatarKrzysztof Wilczyński <kwilczynski@kernel.org>
Reviewed-by: default avatarJohan Hovold <johan+linaro@kernel.org>
Reviewed-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
parent d45736b5
...@@ -210,6 +210,24 @@ ...@@ -210,6 +210,24 @@
#define PCIE_PL_CHK_REG_ERR_ADDR 0xB28 #define PCIE_PL_CHK_REG_ERR_ADDR 0xB28
/*
* 16.0 GT/s (Gen 4) lane margining register definitions
*/
#define GEN4_LANE_MARGINING_1_OFF 0xB80
#define MARGINING_MAX_VOLTAGE_OFFSET GENMASK(29, 24)
#define MARGINING_NUM_VOLTAGE_STEPS GENMASK(22, 16)
#define MARGINING_MAX_TIMING_OFFSET GENMASK(13, 8)
#define MARGINING_NUM_TIMING_STEPS GENMASK(5, 0)
#define GEN4_LANE_MARGINING_2_OFF 0xB84
#define MARGINING_IND_ERROR_SAMPLER BIT(28)
#define MARGINING_SAMPLE_REPORTING_METHOD BIT(27)
#define MARGINING_IND_LEFT_RIGHT_TIMING BIT(26)
#define MARGINING_IND_UP_DOWN_VOLTAGE BIT(25)
#define MARGINING_VOLTAGE_SUPPORTED BIT(24)
#define MARGINING_MAXLANES GENMASK(20, 16)
#define MARGINING_SAMPLE_RATE_TIMING GENMASK(13, 8)
#define MARGINING_SAMPLE_RATE_VOLTAGE GENMASK(5, 0)
/* /*
* iATU Unroll-specific register definitions * iATU Unroll-specific register definitions
* From 4.80 core version the address translation will be made by unroll * From 4.80 core version the address translation will be made by unroll
......
...@@ -45,3 +45,34 @@ void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci) ...@@ -45,3 +45,34 @@ void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci)
dw_pcie_writel_dbi(pci, GEN3_EQ_CONTROL_OFF, reg); 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_16gt_equalization);
void qcom_pcie_common_set_16gt_lane_margining(struct dw_pcie *pci)
{
u32 reg;
reg = dw_pcie_readl_dbi(pci, GEN4_LANE_MARGINING_1_OFF);
reg &= ~(MARGINING_MAX_VOLTAGE_OFFSET |
MARGINING_NUM_VOLTAGE_STEPS |
MARGINING_MAX_TIMING_OFFSET |
MARGINING_NUM_TIMING_STEPS);
reg |= FIELD_PREP(MARGINING_MAX_VOLTAGE_OFFSET, 0x24) |
FIELD_PREP(MARGINING_NUM_VOLTAGE_STEPS, 0x78) |
FIELD_PREP(MARGINING_MAX_TIMING_OFFSET, 0x32) |
FIELD_PREP(MARGINING_NUM_TIMING_STEPS, 0x10);
dw_pcie_writel_dbi(pci, GEN4_LANE_MARGINING_1_OFF, reg);
reg = dw_pcie_readl_dbi(pci, GEN4_LANE_MARGINING_2_OFF);
reg |= MARGINING_IND_ERROR_SAMPLER |
MARGINING_SAMPLE_REPORTING_METHOD |
MARGINING_IND_LEFT_RIGHT_TIMING |
MARGINING_VOLTAGE_SUPPORTED;
reg &= ~(MARGINING_IND_UP_DOWN_VOLTAGE |
MARGINING_MAXLANES |
MARGINING_SAMPLE_RATE_TIMING |
MARGINING_SAMPLE_RATE_VOLTAGE);
reg |= FIELD_PREP(MARGINING_MAXLANES, pci->num_lanes) |
FIELD_PREP(MARGINING_SAMPLE_RATE_TIMING, 0x3f) |
FIELD_PREP(MARGINING_SAMPLE_RATE_VOLTAGE, 0x3f);
dw_pcie_writel_dbi(pci, GEN4_LANE_MARGINING_2_OFF, reg);
}
EXPORT_SYMBOL_GPL(qcom_pcie_common_set_16gt_lane_margining);
...@@ -9,5 +9,6 @@ ...@@ -9,5 +9,6 @@
struct dw_pcie; struct dw_pcie;
void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci); void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci);
void qcom_pcie_common_set_16gt_lane_margining(struct dw_pcie *pci);
#endif #endif
...@@ -487,8 +487,10 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci) ...@@ -487,8 +487,10 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
goto err_disable_resources; goto err_disable_resources;
} }
if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT) if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT) {
qcom_pcie_common_set_16gt_equalization(pci); qcom_pcie_common_set_16gt_equalization(pci);
qcom_pcie_common_set_16gt_lane_margining(pci);
}
/* /*
* The physical address of the MMIO region which is exposed as the BAR * The physical address of the MMIO region which is exposed as the BAR
......
...@@ -296,8 +296,10 @@ static int qcom_pcie_start_link(struct dw_pcie *pci) ...@@ -296,8 +296,10 @@ static int qcom_pcie_start_link(struct dw_pcie *pci)
{ {
struct qcom_pcie *pcie = to_qcom_pcie(pci); struct qcom_pcie *pcie = to_qcom_pcie(pci);
if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT) if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT) {
qcom_pcie_common_set_16gt_equalization(pci); qcom_pcie_common_set_16gt_equalization(pci);
qcom_pcie_common_set_16gt_lane_margining(pci);
}
/* Enable Link Training state machine */ /* Enable Link Training state machine */
if (pcie->cfg->ops->ltssm_enable) if (pcie->cfg->ops->ltssm_enable)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment