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