sparx5_serdes.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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. struct sparx5_serdes_private {
  24. struct device *dev;
  25. void __iomem *regs[NUM_TARGETS];
  26. struct phy *phys[SPX5_SERDES_MAX];
  27. unsigned long coreclock;
  28. };
  29. struct sparx5_serdes_macro {
  30. struct sparx5_serdes_private *priv;
  31. u32 sidx;
  32. u32 stpidx;
  33. enum sparx5_serdes_type serdestype;
  34. enum sparx5_serdes_mode serdesmode;
  35. phy_interface_t portmode;
  36. int speed;
  37. enum phy_media media;
  38. };
  39. /* Read, Write and modify registers content.
  40. * The register definition macros start at the id
  41. */
  42. static inline void __iomem *sdx5_addr(void __iomem *base[],
  43. int id, int tinst, int tcnt,
  44. int gbase, int ginst,
  45. int gcnt, int gwidth,
  46. int raddr, int rinst,
  47. int rcnt, int rwidth)
  48. {
  49. WARN_ON((tinst) >= tcnt);
  50. WARN_ON((ginst) >= gcnt);
  51. WARN_ON((rinst) >= rcnt);
  52. return base[id + (tinst)] +
  53. gbase + ((ginst) * gwidth) +
  54. raddr + ((rinst) * rwidth);
  55. }
  56. static inline void __iomem *sdx5_inst_baseaddr(void __iomem *base,
  57. int gbase, int ginst,
  58. int gcnt, int gwidth,
  59. int raddr, int rinst,
  60. int rcnt, int rwidth)
  61. {
  62. WARN_ON((ginst) >= gcnt);
  63. WARN_ON((rinst) >= rcnt);
  64. return base +
  65. gbase + ((ginst) * gwidth) +
  66. raddr + ((rinst) * rwidth);
  67. }
  68. static inline void sdx5_rmw(u32 val, u32 mask, struct sparx5_serdes_private *priv,
  69. int id, int tinst, int tcnt,
  70. int gbase, int ginst, int gcnt, int gwidth,
  71. int raddr, int rinst, int rcnt, int rwidth)
  72. {
  73. u32 nval;
  74. void __iomem *addr =
  75. sdx5_addr(priv->regs, id, tinst, tcnt,
  76. gbase, ginst, gcnt, gwidth,
  77. raddr, rinst, rcnt, rwidth);
  78. nval = readl(addr);
  79. nval = (nval & ~mask) | (val & mask);
  80. writel(nval, addr);
  81. }
  82. static inline void sdx5_inst_rmw(u32 val, u32 mask, void __iomem *iomem,
  83. int id, int tinst, int tcnt,
  84. int gbase, int ginst, int gcnt, int gwidth,
  85. int raddr, int rinst, int rcnt, int rwidth)
  86. {
  87. u32 nval;
  88. void __iomem *addr =
  89. sdx5_inst_baseaddr(iomem,
  90. gbase, ginst, gcnt, gwidth,
  91. raddr, rinst, rcnt, rwidth);
  92. nval = readl(addr);
  93. nval = (nval & ~mask) | (val & mask);
  94. writel(nval, addr);
  95. }
  96. static inline void sdx5_rmw_addr(u32 val, u32 mask, void __iomem *addr)
  97. {
  98. u32 nval;
  99. nval = readl(addr);
  100. nval = (nval & ~mask) | (val & mask);
  101. writel(nval, addr);
  102. }
  103. static inline void __iomem *sdx5_inst_get(struct sparx5_serdes_private *priv,
  104. int id, int tinst)
  105. {
  106. return priv->regs[id + tinst];
  107. }
  108. static inline void __iomem *sdx5_inst_addr(void __iomem *iomem,
  109. int id, int tinst, int tcnt,
  110. int gbase,
  111. int ginst, int gcnt, int gwidth,
  112. int raddr,
  113. int rinst, int rcnt, int rwidth)
  114. {
  115. return sdx5_inst_baseaddr(iomem, gbase, ginst, gcnt, gwidth,
  116. raddr, rinst, rcnt, rwidth);
  117. }
  118. #endif /* _SPARX5_SERDES_REGS_H_ */