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