Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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.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>

authored by

Shashank Babu Chinta Venkata and committed by
Krzysztof Wilczyński
d14bc28a d45736b5

+56 -2
+18
drivers/pci/controller/dwc/pcie-designware.h
··· 211 211 #define PCIE_PL_CHK_REG_ERR_ADDR 0xB28 212 212 213 213 /* 214 + * 16.0 GT/s (Gen 4) lane margining register definitions 215 + */ 216 + #define GEN4_LANE_MARGINING_1_OFF 0xB80 217 + #define MARGINING_MAX_VOLTAGE_OFFSET GENMASK(29, 24) 218 + #define MARGINING_NUM_VOLTAGE_STEPS GENMASK(22, 16) 219 + #define MARGINING_MAX_TIMING_OFFSET GENMASK(13, 8) 220 + #define MARGINING_NUM_TIMING_STEPS GENMASK(5, 0) 221 + 222 + #define GEN4_LANE_MARGINING_2_OFF 0xB84 223 + #define MARGINING_IND_ERROR_SAMPLER BIT(28) 224 + #define MARGINING_SAMPLE_REPORTING_METHOD BIT(27) 225 + #define MARGINING_IND_LEFT_RIGHT_TIMING BIT(26) 226 + #define MARGINING_IND_UP_DOWN_VOLTAGE BIT(25) 227 + #define MARGINING_VOLTAGE_SUPPORTED BIT(24) 228 + #define MARGINING_MAXLANES GENMASK(20, 16) 229 + #define MARGINING_SAMPLE_RATE_TIMING GENMASK(13, 8) 230 + #define MARGINING_SAMPLE_RATE_VOLTAGE GENMASK(5, 0) 231 + /* 214 232 * iATU Unroll-specific register definitions 215 233 * From 4.80 core version the address translation will be made by unroll 216 234 */
+31
drivers/pci/controller/dwc/pcie-qcom-common.c
··· 45 45 dw_pcie_writel_dbi(pci, GEN3_EQ_CONTROL_OFF, reg); 46 46 } 47 47 EXPORT_SYMBOL_GPL(qcom_pcie_common_set_16gt_equalization); 48 + 49 + void qcom_pcie_common_set_16gt_lane_margining(struct dw_pcie *pci) 50 + { 51 + u32 reg; 52 + 53 + reg = dw_pcie_readl_dbi(pci, GEN4_LANE_MARGINING_1_OFF); 54 + reg &= ~(MARGINING_MAX_VOLTAGE_OFFSET | 55 + MARGINING_NUM_VOLTAGE_STEPS | 56 + MARGINING_MAX_TIMING_OFFSET | 57 + MARGINING_NUM_TIMING_STEPS); 58 + reg |= FIELD_PREP(MARGINING_MAX_VOLTAGE_OFFSET, 0x24) | 59 + FIELD_PREP(MARGINING_NUM_VOLTAGE_STEPS, 0x78) | 60 + FIELD_PREP(MARGINING_MAX_TIMING_OFFSET, 0x32) | 61 + FIELD_PREP(MARGINING_NUM_TIMING_STEPS, 0x10); 62 + dw_pcie_writel_dbi(pci, GEN4_LANE_MARGINING_1_OFF, reg); 63 + 64 + reg = dw_pcie_readl_dbi(pci, GEN4_LANE_MARGINING_2_OFF); 65 + reg |= MARGINING_IND_ERROR_SAMPLER | 66 + MARGINING_SAMPLE_REPORTING_METHOD | 67 + MARGINING_IND_LEFT_RIGHT_TIMING | 68 + MARGINING_VOLTAGE_SUPPORTED; 69 + reg &= ~(MARGINING_IND_UP_DOWN_VOLTAGE | 70 + MARGINING_MAXLANES | 71 + MARGINING_SAMPLE_RATE_TIMING | 72 + MARGINING_SAMPLE_RATE_VOLTAGE); 73 + reg |= FIELD_PREP(MARGINING_MAXLANES, pci->num_lanes) | 74 + FIELD_PREP(MARGINING_SAMPLE_RATE_TIMING, 0x3f) | 75 + FIELD_PREP(MARGINING_SAMPLE_RATE_VOLTAGE, 0x3f); 76 + dw_pcie_writel_dbi(pci, GEN4_LANE_MARGINING_2_OFF, reg); 77 + } 78 + EXPORT_SYMBOL_GPL(qcom_pcie_common_set_16gt_lane_margining);
+1
drivers/pci/controller/dwc/pcie-qcom-common.h
··· 9 9 struct dw_pcie; 10 10 11 11 void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci); 12 + void qcom_pcie_common_set_16gt_lane_margining(struct dw_pcie *pci); 12 13 13 14 #endif
+3 -1
drivers/pci/controller/dwc/pcie-qcom-ep.c
··· 487 487 goto err_disable_resources; 488 488 } 489 489 490 - if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT) 490 + if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT) { 491 491 qcom_pcie_common_set_16gt_equalization(pci); 492 + qcom_pcie_common_set_16gt_lane_margining(pci); 493 + } 492 494 493 495 /* 494 496 * The physical address of the MMIO region which is exposed as the BAR
+3 -1
drivers/pci/controller/dwc/pcie-qcom.c
··· 296 296 { 297 297 struct qcom_pcie *pcie = to_qcom_pcie(pci); 298 298 299 - if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT) 299 + if (pcie_link_speed[pci->max_link_speed] == PCIE_SPEED_16_0GT) { 300 300 qcom_pcie_common_set_16gt_equalization(pci); 301 + qcom_pcie_common_set_16gt_lane_margining(pci); 302 + } 301 303 302 304 /* Enable Link Training state machine */ 303 305 if (pcie->cfg->ops->ltssm_enable)