Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0+
0002  * Microchip Sparx5 SerDes driver
0003  *
0004  * Copyright (c) 2020 Microchip Technology Inc.
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 /* Read, Write and modify registers content.
0049  * The register definition macros start at the id
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 /* _SPARX5_SERDES_REGS_H_ */