pcie_layerscape.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2017-2020 NXP
  4. * Copyright 2014-2015 Freescale Semiconductor, Inc.
  5. * Layerscape PCIe driver
  6. */
  7. #include <common.h>
  8. #include <log.h>
  9. #include <asm/io.h>
  10. #include <errno.h>
  11. #include <malloc.h>
  12. #if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \
  13. defined(CONFIG_ARM)
  14. #include <asm/arch/clock.h>
  15. #endif
  16. #include "pcie_layerscape.h"
  17. DECLARE_GLOBAL_DATA_PTR;
  18. LIST_HEAD(ls_pcie_list);
  19. unsigned int dbi_readl(struct ls_pcie *pcie, unsigned int offset)
  20. {
  21. return in_le32(pcie->dbi + offset);
  22. }
  23. void dbi_writel(struct ls_pcie *pcie, unsigned int value, unsigned int offset)
  24. {
  25. out_le32(pcie->dbi + offset, value);
  26. }
  27. unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int offset)
  28. {
  29. if (pcie->big_endian)
  30. return in_be32(pcie->ctrl + offset);
  31. else
  32. return in_le32(pcie->ctrl + offset);
  33. }
  34. void ctrl_writel(struct ls_pcie *pcie, unsigned int value,
  35. unsigned int offset)
  36. {
  37. if (pcie->big_endian)
  38. out_be32(pcie->ctrl + offset, value);
  39. else
  40. out_le32(pcie->ctrl + offset, value);
  41. }
  42. void ls_pcie_dbi_ro_wr_en(struct ls_pcie *pcie)
  43. {
  44. u32 reg, val;
  45. reg = PCIE_MISC_CONTROL_1_OFF;
  46. val = dbi_readl(pcie, reg);
  47. val |= PCIE_DBI_RO_WR_EN;
  48. dbi_writel(pcie, val, reg);
  49. }
  50. void ls_pcie_dbi_ro_wr_dis(struct ls_pcie *pcie)
  51. {
  52. u32 reg, val;
  53. reg = PCIE_MISC_CONTROL_1_OFF;
  54. val = dbi_readl(pcie, reg);
  55. val &= ~PCIE_DBI_RO_WR_EN;
  56. dbi_writel(pcie, val, reg);
  57. }
  58. static int ls_pcie_ltssm(struct ls_pcie *pcie)
  59. {
  60. u32 state;
  61. uint svr;
  62. svr = get_svr();
  63. if (((svr >> SVR_VAR_PER_SHIFT) & SVR_LS102XA_MASK) == SVR_LS102XA) {
  64. state = ctrl_readl(pcie, LS1021_PEXMSCPORTSR(pcie->idx));
  65. state = (state >> LS1021_LTSSM_STATE_SHIFT) & LTSSM_STATE_MASK;
  66. } else {
  67. state = ctrl_readl(pcie, PCIE_PF_DBG) & LTSSM_STATE_MASK;
  68. }
  69. return state;
  70. }
  71. int ls_pcie_link_up(struct ls_pcie *pcie)
  72. {
  73. int ltssm;
  74. ltssm = ls_pcie_ltssm(pcie);
  75. if (ltssm < LTSSM_PCIE_L0)
  76. return 0;
  77. return 1;
  78. }
  79. void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type,
  80. u64 phys, u64 bus_addr, u64 size)
  81. {
  82. dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | idx, PCIE_ATU_VIEWPORT);
  83. dbi_writel(pcie, (u32)phys, PCIE_ATU_LOWER_BASE);
  84. dbi_writel(pcie, phys >> 32, PCIE_ATU_UPPER_BASE);
  85. dbi_writel(pcie, (u32)phys + size - 1, PCIE_ATU_LIMIT);
  86. dbi_writel(pcie, (u32)bus_addr, PCIE_ATU_LOWER_TARGET);
  87. dbi_writel(pcie, bus_addr >> 32, PCIE_ATU_UPPER_TARGET);
  88. dbi_writel(pcie, type, PCIE_ATU_CR1);
  89. dbi_writel(pcie, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
  90. }
  91. /* Use bar match mode and MEM type as default */
  92. void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, u32 vf_flag,
  93. int type, int idx, int bar, u64 phys)
  94. {
  95. dbi_writel(pcie, PCIE_ATU_REGION_INBOUND | idx, PCIE_ATU_VIEWPORT);
  96. dbi_writel(pcie, (u32)phys, PCIE_ATU_LOWER_TARGET);
  97. dbi_writel(pcie, phys >> 32, PCIE_ATU_UPPER_TARGET);
  98. dbi_writel(pcie, type | PCIE_ATU_FUNC_NUM(pf), PCIE_ATU_CR1);
  99. dbi_writel(pcie, PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE |
  100. (vf_flag ? PCIE_ATU_FUNC_NUM_MATCH_EN : 0) |
  101. (vf_flag ? PCIE_ATU_VFBAR_MATCH_MODE_EN : 0) |
  102. PCIE_ATU_BAR_NUM(bar), PCIE_ATU_CR2);
  103. }
  104. void ls_pcie_dump_atu(struct ls_pcie *pcie, u32 win_num, u32 type)
  105. {
  106. int win_idx;
  107. for (win_idx = 0; win_idx < win_num; win_idx++) {
  108. dbi_writel(pcie, type | win_idx, PCIE_ATU_VIEWPORT);
  109. debug("iATU%d:\n", win_idx);
  110. debug("\tLOWER PHYS 0x%08x\n",
  111. dbi_readl(pcie, PCIE_ATU_LOWER_BASE));
  112. debug("\tUPPER PHYS 0x%08x\n",
  113. dbi_readl(pcie, PCIE_ATU_UPPER_BASE));
  114. if (type == PCIE_ATU_REGION_OUTBOUND) {
  115. debug("\tLOWER BUS 0x%08x\n",
  116. dbi_readl(pcie, PCIE_ATU_LOWER_TARGET));
  117. debug("\tUPPER BUS 0x%08x\n",
  118. dbi_readl(pcie, PCIE_ATU_UPPER_TARGET));
  119. debug("\tLIMIT 0x%08x\n",
  120. dbi_readl(pcie, PCIE_ATU_LIMIT));
  121. }
  122. debug("\tCR1 0x%08x\n",
  123. dbi_readl(pcie, PCIE_ATU_CR1));
  124. debug("\tCR2 0x%08x\n",
  125. dbi_readl(pcie, PCIE_ATU_CR2));
  126. }
  127. }