pcie-qcom-common.c 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  4. */
  5. #include <linux/pci.h>
  6. #include "pcie-designware.h"
  7. #include "pcie-qcom-common.h"
  8. void qcom_pcie_common_set_equalization(struct dw_pcie *pci)
  9. {
  10. struct device *dev = pci->dev;
  11. u32 reg;
  12. u16 speed;
  13. /*
  14. * GEN3_RELATED_OFF register is repurposed to apply equalization
  15. * settings at various data transmission rates through registers namely
  16. * GEN3_EQ_*. The RATE_SHADOW_SEL bit field of GEN3_RELATED_OFF
  17. * determines the data rate for which these equalization settings are
  18. * applied.
  19. */
  20. for (speed = PCIE_SPEED_8_0GT; speed <= pcie_link_speed[pci->max_link_speed]; speed++) {
  21. if (speed > PCIE_SPEED_32_0GT) {
  22. dev_warn(dev, "Skipped equalization settings for unsupported data rate\n");
  23. break;
  24. }
  25. reg = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
  26. reg &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
  27. reg &= ~GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK;
  28. reg |= FIELD_PREP(GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK,
  29. speed - PCIE_SPEED_8_0GT);
  30. dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, reg);
  31. reg = dw_pcie_readl_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF);
  32. reg &= ~(GEN3_EQ_FMDC_T_MIN_PHASE23 |
  33. GEN3_EQ_FMDC_N_EVALS |
  34. GEN3_EQ_FMDC_MAX_PRE_CURSOR_DELTA |
  35. GEN3_EQ_FMDC_MAX_POST_CURSOR_DELTA);
  36. reg |= FIELD_PREP(GEN3_EQ_FMDC_T_MIN_PHASE23, 0x1) |
  37. FIELD_PREP(GEN3_EQ_FMDC_N_EVALS, 0xd) |
  38. FIELD_PREP(GEN3_EQ_FMDC_MAX_PRE_CURSOR_DELTA, 0x5) |
  39. FIELD_PREP(GEN3_EQ_FMDC_MAX_POST_CURSOR_DELTA, 0x5);
  40. dw_pcie_writel_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF, reg);
  41. reg = dw_pcie_readl_dbi(pci, GEN3_EQ_CONTROL_OFF);
  42. reg &= ~(GEN3_EQ_CONTROL_OFF_FB_MODE |
  43. GEN3_EQ_CONTROL_OFF_PHASE23_EXIT_MODE |
  44. GEN3_EQ_CONTROL_OFF_FOM_INC_INITIAL_EVAL |
  45. GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC);
  46. dw_pcie_writel_dbi(pci, GEN3_EQ_CONTROL_OFF, reg);
  47. }
  48. }
  49. EXPORT_SYMBOL_GPL(qcom_pcie_common_set_equalization);
  50. void qcom_pcie_common_set_16gt_lane_margining(struct dw_pcie *pci)
  51. {
  52. u32 reg;
  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. reg = dw_pcie_readl_dbi(pci, GEN4_LANE_MARGINING_2_OFF);
  64. reg |= MARGINING_IND_ERROR_SAMPLER |
  65. MARGINING_SAMPLE_REPORTING_METHOD |
  66. MARGINING_IND_LEFT_RIGHT_TIMING |
  67. MARGINING_VOLTAGE_SUPPORTED;
  68. reg &= ~(MARGINING_IND_UP_DOWN_VOLTAGE |
  69. MARGINING_MAXLANES |
  70. MARGINING_SAMPLE_RATE_TIMING |
  71. MARGINING_SAMPLE_RATE_VOLTAGE);
  72. reg |= FIELD_PREP(MARGINING_MAXLANES, pci->num_lanes) |
  73. FIELD_PREP(MARGINING_SAMPLE_RATE_TIMING, 0x3f) |
  74. FIELD_PREP(MARGINING_SAMPLE_RATE_VOLTAGE, 0x3f);
  75. dw_pcie_writel_dbi(pci, GEN4_LANE_MARGINING_2_OFF, reg);
  76. }
  77. EXPORT_SYMBOL_GPL(qcom_pcie_common_set_16gt_lane_margining);