1 /* SPDX-License-Identifier: GPL-2.0+
2 * Microchip Sparx5 SerDes driver
4 * Copyright (c) 2020 Microchip Technology Inc.
7 #ifndef _SPARX5_SERDES_H_
8 #define _SPARX5_SERDES_H_
10 #include "sparx5_serdes_regs.h"
12 #define SPX5_SERDES_MAX 33
14 enum sparx5_serdes_type {
20 enum sparx5_serdes_mode {
25 SPX5_SD_MODE_1000BASEX,
29 enum sparx5_10g28cmu_mode {
30 SPX5_SD10G28_CMU_MAIN = 0,
31 SPX5_SD10G28_CMU_AUX1 = 1,
32 SPX5_SD10G28_CMU_AUX2 = 3,
33 SPX5_SD10G28_CMU_NONE = 4,
43 struct sparx5_serdes_macro {
44 struct sparx5_serdes_private *priv;
47 enum sparx5_serdes_type serdestype;
48 enum sparx5_serdes_mode serdesmode;
49 phy_interface_t portmode;
54 struct sparx5_serdes_consts {
59 struct sparx5_serdes_ops {
60 void (*serdes_type_set)(struct sparx5_serdes_macro *macro, int sidx);
61 int (*serdes_cmu_get)(enum sparx5_10g28cmu_mode mode, int sd_index);
64 struct sparx5_serdes_match_data {
65 enum sparx5_target type;
66 const struct sparx5_serdes_consts consts;
67 const struct sparx5_serdes_ops ops;
68 const struct sparx5_serdes_io_resource *iomap;
70 const unsigned int *tsize;
73 struct sparx5_serdes_private {
75 void __iomem *regs[NUM_TARGETS];
76 struct phy *phys[SPX5_SERDES_MAX];
77 unsigned long coreclock;
78 const struct sparx5_serdes_match_data *data;
81 /* Read, Write and modify registers content.
82 * The register definition macros start at the id
84 static inline void __iomem *sdx5_addr(void __iomem *base[],
85 int id, int tinst, int tcnt,
91 WARN_ON((tinst) >= tcnt);
92 WARN_ON((ginst) >= gcnt);
93 WARN_ON((rinst) >= rcnt);
94 return base[id + (tinst)] +
95 gbase + ((ginst) * gwidth) +
96 raddr + ((rinst) * rwidth);
99 static inline void __iomem *sdx5_inst_baseaddr(void __iomem *base,
100 int gbase, int ginst,
101 int gcnt, int gwidth,
102 int raddr, int rinst,
103 int rcnt, int rwidth)
105 WARN_ON((ginst) >= gcnt);
106 WARN_ON((rinst) >= rcnt);
108 gbase + ((ginst) * gwidth) +
109 raddr + ((rinst) * rwidth);
112 static inline void sdx5_rmw(u32 val, u32 mask, struct sparx5_serdes_private *priv,
113 int id, int tinst, int tcnt,
114 int gbase, int ginst, int gcnt, int gwidth,
115 int raddr, int rinst, int rcnt, int rwidth)
119 sdx5_addr(priv->regs, id, tinst, tcnt,
120 gbase, ginst, gcnt, gwidth,
121 raddr, rinst, rcnt, rwidth);
123 nval = (nval & ~mask) | (val & mask);
127 static inline void sdx5_inst_rmw(u32 val, u32 mask, void __iomem *iomem,
128 int id, int tinst, int tcnt,
129 int gbase, int ginst, int gcnt, int gwidth,
130 int raddr, int rinst, int rcnt, int rwidth)
134 sdx5_inst_baseaddr(iomem,
135 gbase, ginst, gcnt, gwidth,
136 raddr, rinst, rcnt, rwidth);
138 nval = (nval & ~mask) | (val & mask);
142 static inline void sdx5_rmw_addr(u32 val, u32 mask, void __iomem *addr)
147 nval = (nval & ~mask) | (val & mask);
151 static inline void __iomem *sdx5_inst_get(struct sparx5_serdes_private *priv,
154 return priv->regs[id + tinst];
157 static inline void __iomem *sdx5_inst_addr(void __iomem *iomem,
158 int id, int tinst, int tcnt,
160 int ginst, int gcnt, int gwidth,
162 int rinst, int rcnt, int rwidth)
164 return sdx5_inst_baseaddr(iomem, gbase, ginst, gcnt, gwidth,
165 raddr, rinst, rcnt, rwidth);
169 #endif /* _SPARX5_SERDES_REGS_H_ */