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