GNU Linux-libre 6.8.9-gnu
[releases.git] / drivers / phy / microchip / sparx5_serdes.h
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
14 enum sparx5_serdes_type {
15         SPX5_SDT_6G  = 6,
16         SPX5_SDT_10G = 10,
17         SPX5_SDT_25G = 25,
18 };
19
20 enum 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
29 struct 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
36 struct 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  */
50 static 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
65 static 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
78 static 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
93 static 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
108 static 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
117 static 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
123 static 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_ */