sparx5_serdes.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /* SPDX-License-Identifier: GPL-2.0+
  2. * Microchip Sparx5 SerDes driver
  3. *
  4. * Copyright (c) 2020 Microchip Technology Inc.
  5. */
  6. #ifndef _SPARX5_SERDES_H_
  7. #define _SPARX5_SERDES_H_
  8. #include "sparx5_serdes_regs.h"
  9. #define SPX5_SERDES_MAX 33
  10. enum sparx5_serdes_type {
  11. SPX5_SDT_6G = 6,
  12. SPX5_SDT_10G = 10,
  13. SPX5_SDT_25G = 25,
  14. };
  15. enum sparx5_serdes_mode {
  16. SPX5_SD_MODE_NONE,
  17. SPX5_SD_MODE_2G5,
  18. SPX5_SD_MODE_QSGMII,
  19. SPX5_SD_MODE_100FX,
  20. SPX5_SD_MODE_1000BASEX,
  21. SPX5_SD_MODE_SFI,
  22. };
  23. enum sparx5_10g28cmu_mode {
  24. SPX5_SD10G28_CMU_MAIN = 0,
  25. SPX5_SD10G28_CMU_AUX1 = 1,
  26. SPX5_SD10G28_CMU_AUX2 = 3,
  27. SPX5_SD10G28_CMU_NONE = 4,
  28. SPX5_SD10G28_CMU_MAX,
  29. };
  30. enum sparx5_target {
  31. SPX5_TARGET_SPARX5,
  32. SPX5_TARGET_LAN969X,
  33. };
  34. struct sparx5_serdes_macro {
  35. struct sparx5_serdes_private *priv;
  36. u32 sidx;
  37. u32 stpidx;
  38. enum sparx5_serdes_type serdestype;
  39. enum sparx5_serdes_mode serdesmode;
  40. phy_interface_t portmode;
  41. int speed;
  42. enum phy_media media;
  43. };
  44. struct sparx5_serdes_consts {
  45. int sd_max;
  46. int cmu_max;
  47. };
  48. struct sparx5_serdes_ops {
  49. void (*serdes_type_set)(struct sparx5_serdes_macro *macro, int sidx);
  50. int (*serdes_cmu_get)(enum sparx5_10g28cmu_mode mode, int sd_index);
  51. };
  52. struct sparx5_serdes_match_data {
  53. enum sparx5_target type;
  54. const struct sparx5_serdes_consts consts;
  55. const struct sparx5_serdes_ops ops;
  56. const struct sparx5_serdes_io_resource *iomap;
  57. int iomap_size;
  58. const unsigned int *tsize;
  59. };
  60. struct sparx5_serdes_private {
  61. struct device *dev;
  62. void __iomem *regs[NUM_TARGETS];
  63. struct phy *phys[SPX5_SERDES_MAX];
  64. unsigned long coreclock;
  65. const struct sparx5_serdes_match_data *data;
  66. };
  67. /* Read, Write and modify registers content.
  68. * The register definition macros start at the id
  69. */
  70. static inline void __iomem *sdx5_addr(void __iomem *base[],
  71. int id, int tinst, int tcnt,
  72. int gbase, int ginst,
  73. int gcnt, int gwidth,
  74. int raddr, int rinst,
  75. int rcnt, int rwidth)
  76. {
  77. WARN_ON((tinst) >= tcnt);
  78. WARN_ON((ginst) >= gcnt);
  79. WARN_ON((rinst) >= rcnt);
  80. return base[id + (tinst)] +
  81. gbase + ((ginst) * gwidth) +
  82. raddr + ((rinst) * rwidth);
  83. }
  84. static inline void __iomem *sdx5_inst_baseaddr(void __iomem *base,
  85. int gbase, int ginst,
  86. int gcnt, int gwidth,
  87. int raddr, int rinst,
  88. int rcnt, int rwidth)
  89. {
  90. WARN_ON((ginst) >= gcnt);
  91. WARN_ON((rinst) >= rcnt);
  92. return base +
  93. gbase + ((ginst) * gwidth) +
  94. raddr + ((rinst) * rwidth);
  95. }
  96. static inline void sdx5_rmw(u32 val, u32 mask, struct sparx5_serdes_private *priv,
  97. int id, int tinst, int tcnt,
  98. int gbase, int ginst, int gcnt, int gwidth,
  99. int raddr, int rinst, int rcnt, int rwidth)
  100. {
  101. u32 nval;
  102. void __iomem *addr =
  103. sdx5_addr(priv->regs, id, tinst, tcnt,
  104. gbase, ginst, gcnt, gwidth,
  105. raddr, rinst, rcnt, rwidth);
  106. nval = readl(addr);
  107. nval = (nval & ~mask) | (val & mask);
  108. writel(nval, addr);
  109. }
  110. static inline void sdx5_inst_rmw(u32 val, u32 mask, void __iomem *iomem,
  111. int id, int tinst, int tcnt,
  112. int gbase, int ginst, int gcnt, int gwidth,
  113. int raddr, int rinst, int rcnt, int rwidth)
  114. {
  115. u32 nval;
  116. void __iomem *addr =
  117. sdx5_inst_baseaddr(iomem,
  118. gbase, ginst, gcnt, gwidth,
  119. raddr, rinst, rcnt, rwidth);
  120. nval = readl(addr);
  121. nval = (nval & ~mask) | (val & mask);
  122. writel(nval, addr);
  123. }
  124. static inline void sdx5_rmw_addr(u32 val, u32 mask, void __iomem *addr)
  125. {
  126. u32 nval;
  127. nval = readl(addr);
  128. nval = (nval & ~mask) | (val & mask);
  129. writel(nval, addr);
  130. }
  131. static inline void __iomem *sdx5_inst_get(struct sparx5_serdes_private *priv,
  132. int id, int tinst)
  133. {
  134. return priv->regs[id + tinst];
  135. }
  136. static inline void __iomem *sdx5_inst_addr(void __iomem *iomem,
  137. int id, int tinst, int tcnt,
  138. int gbase,
  139. int ginst, int gcnt, int gwidth,
  140. int raddr,
  141. int rinst, int rcnt, int rwidth)
  142. {
  143. return sdx5_inst_baseaddr(iomem, gbase, ginst, gcnt, gwidth,
  144. raddr, rinst, rcnt, rwidth);
  145. }
  146. #endif /* _SPARX5_SERDES_REGS_H_ */