0001
0002
0003
0004
0005
0006
0007 #ifndef _SPARX5_SERDES_H_
0008 #define _SPARX5_SERDES_H_
0009
0010 #include "sparx5_serdes_regs.h"
0011
0012 #define SPX5_SERDES_MAX 33
0013
0014 enum sparx5_serdes_type {
0015 SPX5_SDT_6G = 6,
0016 SPX5_SDT_10G = 10,
0017 SPX5_SDT_25G = 25,
0018 };
0019
0020 enum sparx5_serdes_mode {
0021 SPX5_SD_MODE_NONE,
0022 SPX5_SD_MODE_2G5,
0023 SPX5_SD_MODE_QSGMII,
0024 SPX5_SD_MODE_100FX,
0025 SPX5_SD_MODE_1000BASEX,
0026 SPX5_SD_MODE_SFI,
0027 };
0028
0029 struct sparx5_serdes_private {
0030 struct device *dev;
0031 void __iomem *regs[NUM_TARGETS];
0032 struct phy *phys[SPX5_SERDES_MAX];
0033 bool cmu_enabled;
0034 unsigned long coreclock;
0035 };
0036
0037 struct sparx5_serdes_macro {
0038 struct sparx5_serdes_private *priv;
0039 u32 sidx;
0040 u32 stpidx;
0041 enum sparx5_serdes_type serdestype;
0042 enum sparx5_serdes_mode serdesmode;
0043 phy_interface_t portmode;
0044 int speed;
0045 enum phy_media media;
0046 };
0047
0048
0049
0050
0051 static inline void __iomem *sdx5_addr(void __iomem *base[],
0052 int id, int tinst, int tcnt,
0053 int gbase, int ginst,
0054 int gcnt, int gwidth,
0055 int raddr, int rinst,
0056 int rcnt, int rwidth)
0057 {
0058 WARN_ON((tinst) >= tcnt);
0059 WARN_ON((ginst) >= gcnt);
0060 WARN_ON((rinst) >= rcnt);
0061 return base[id + (tinst)] +
0062 gbase + ((ginst) * gwidth) +
0063 raddr + ((rinst) * rwidth);
0064 }
0065
0066 static inline void __iomem *sdx5_inst_baseaddr(void __iomem *base,
0067 int gbase, int ginst,
0068 int gcnt, int gwidth,
0069 int raddr, int rinst,
0070 int rcnt, int rwidth)
0071 {
0072 WARN_ON((ginst) >= gcnt);
0073 WARN_ON((rinst) >= rcnt);
0074 return base +
0075 gbase + ((ginst) * gwidth) +
0076 raddr + ((rinst) * rwidth);
0077 }
0078
0079 static inline void sdx5_rmw(u32 val, u32 mask, struct sparx5_serdes_private *priv,
0080 int id, int tinst, int tcnt,
0081 int gbase, int ginst, int gcnt, int gwidth,
0082 int raddr, int rinst, int rcnt, int rwidth)
0083 {
0084 u32 nval;
0085 void __iomem *addr =
0086 sdx5_addr(priv->regs, id, tinst, tcnt,
0087 gbase, ginst, gcnt, gwidth,
0088 raddr, rinst, rcnt, rwidth);
0089 nval = readl(addr);
0090 nval = (nval & ~mask) | (val & mask);
0091 writel(nval, addr);
0092 }
0093
0094 static inline void sdx5_inst_rmw(u32 val, u32 mask, void __iomem *iomem,
0095 int id, int tinst, int tcnt,
0096 int gbase, int ginst, int gcnt, int gwidth,
0097 int raddr, int rinst, int rcnt, int rwidth)
0098 {
0099 u32 nval;
0100 void __iomem *addr =
0101 sdx5_inst_baseaddr(iomem,
0102 gbase, ginst, gcnt, gwidth,
0103 raddr, rinst, rcnt, rwidth);
0104 nval = readl(addr);
0105 nval = (nval & ~mask) | (val & mask);
0106 writel(nval, addr);
0107 }
0108
0109 static inline void sdx5_rmw_addr(u32 val, u32 mask, void __iomem *addr)
0110 {
0111 u32 nval;
0112
0113 nval = readl(addr);
0114 nval = (nval & ~mask) | (val & mask);
0115 writel(nval, addr);
0116 }
0117
0118 static inline void __iomem *sdx5_inst_get(struct sparx5_serdes_private *priv,
0119 int id, int tinst)
0120 {
0121 return priv->regs[id + tinst];
0122 }
0123
0124 static inline void __iomem *sdx5_inst_addr(void __iomem *iomem,
0125 int id, int tinst, int tcnt,
0126 int gbase,
0127 int ginst, int gcnt, int gwidth,
0128 int raddr,
0129 int rinst, int rcnt, int rwidth)
0130 {
0131 return sdx5_inst_baseaddr(iomem, gbase, ginst, gcnt, gwidth,
0132 raddr, rinst, rcnt, rwidth);
0133 }
0134
0135
0136 #endif