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