33dd002146c1ee035f5b660f9e58993199ade696
[oweals/u-boot.git] / drivers / net / mscc_eswitch / jr2_switch.c
1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2 /*
3  * Copyright (c) 2018 Microsemi Corporation
4  */
5
6 #include <common.h>
7 #include <config.h>
8 #include <dm.h>
9 #include <malloc.h>
10 #include <dm/of_access.h>
11 #include <dm/of_addr.h>
12 #include <fdt_support.h>
13 #include <linux/io.h>
14 #include <linux/ioport.h>
15 #include <miiphy.h>
16 #include <net.h>
17 #include <wait_bit.h>
18
19 #include <dt-bindings/mscc/jr2_data.h>
20 #include "mscc_xfer.h"
21 #include "mscc_miim.h"
22
23 #define ANA_AC_RAM_CTRL_RAM_INIT                0x94358
24 #define ANA_AC_STAT_GLOBAL_CFG_PORT_RESET       0x94370
25
26 #define ANA_CL_PORT_VLAN_CFG(x)                 (0x24018 + 0xc8 * (x))
27 #define         ANA_CL_PORT_VLAN_CFG_AWARE_ENA                  BIT(19)
28 #define         ANA_CL_PORT_VLAN_CFG_POP_CNT(x)                 ((x) << 17)
29
30 #define ANA_L2_COMMON_FWD_CFG                   0x8a2a8
31 #define         ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA BIT(6)
32
33 #define ASM_CFG_STAT_CFG                        0x3508
34 #define ASM_CFG_PORT(x)                         (0x36c4 + 0x4 * (x))
35 #define         ASM_CFG_PORT_NO_PREAMBLE_ENA            BIT(8)
36 #define         ASM_CFG_PORT_INJ_FORMAT_CFG(x)          ((x) << 1)
37 #define ASM_RAM_CTRL_RAM_INIT                   0x39b8
38
39 #define DEV_DEV_CFG_DEV_RST_CTRL                0x0
40 #define         DEV_DEV_CFG_DEV_RST_CTRL_SPEED_SEL(x)   ((x) << 20)
41 #define DEV_MAC_CFG_MAC_ENA             0x1c
42 #define         DEV_MAC_CFG_MAC_ENA_RX_ENA              BIT(4)
43 #define         DEV_MAC_CFG_MAC_ENA_TX_ENA              BIT(0)
44 #define DEV_MAC_CFG_MAC_IFG             0x34
45 #define         DEV_MAC_CFG_MAC_IFG_TX_IFG(x)           ((x) << 8)
46 #define         DEV_MAC_CFG_MAC_IFG_RX_IFG2(x)          ((x) << 4)
47 #define         DEV_MAC_CFG_MAC_IFG_RX_IFG1(x)          (x)
48 #define DEV_PCS1G_CFG_PCS1G_CFG         0x40
49 #define         DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA         BIT(0)
50 #define DEV_PCS1G_CFG_PCS1G_MODE        0x44
51 #define DEV_PCS1G_CFG_PCS1G_SD          0x48
52 #define DEV_PCS1G_CFG_PCS1G_ANEG        0x4c
53 #define         DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(x) ((x) << 16)
54
55 #define DSM_RAM_CTRL_RAM_INIT           0x8
56
57 #define HSIO_ANA_SERDES1G_DES_CFG               0xac
58 #define         HSIO_ANA_SERDES1G_DES_CFG_BW_HYST(x)            ((x) << 1)
59 #define         HSIO_ANA_SERDES1G_DES_CFG_BW_ANA(x)             ((x) << 5)
60 #define         HSIO_ANA_SERDES1G_DES_CFG_MBTR_CTRL(x)          ((x) << 8)
61 #define         HSIO_ANA_SERDES1G_DES_CFG_PHS_CTRL(x)           ((x) << 13)
62 #define HSIO_ANA_SERDES1G_IB_CFG                0xb0
63 #define         HSIO_ANA_SERDES1G_IB_CFG_RESISTOR_CTRL(x)       (x)
64 #define         HSIO_ANA_SERDES1G_IB_CFG_EQ_GAIN(x)             ((x) << 6)
65 #define         HSIO_ANA_SERDES1G_IB_CFG_ENA_OFFSET_COMP        BIT(9)
66 #define         HSIO_ANA_SERDES1G_IB_CFG_ENA_DETLEV             BIT(11)
67 #define         HSIO_ANA_SERDES1G_IB_CFG_ENA_CMV_TERM           BIT(13)
68 #define         HSIO_ANA_SERDES1G_IB_CFG_DET_LEV(x)             ((x) << 19)
69 #define         HSIO_ANA_SERDES1G_IB_CFG_ACJTAG_HYST(x)         ((x) << 24)
70 #define HSIO_ANA_SERDES1G_OB_CFG                0xb4
71 #define         HSIO_ANA_SERDES1G_OB_CFG_RESISTOR_CTRL(x)       (x)
72 #define         HSIO_ANA_SERDES1G_OB_CFG_VCM_CTRL(x)            ((x) << 4)
73 #define         HSIO_ANA_SERDES1G_OB_CFG_CMM_BIAS_CTRL(x)       ((x) << 10)
74 #define         HSIO_ANA_SERDES1G_OB_CFG_AMP_CTRL(x)            ((x) << 13)
75 #define         HSIO_ANA_SERDES1G_OB_CFG_SLP(x)                 ((x) << 17)
76 #define HSIO_ANA_SERDES1G_SER_CFG               0xb8
77 #define HSIO_ANA_SERDES1G_COMMON_CFG            0xbc
78 #define         HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE            BIT(0)
79 #define         HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE           BIT(18)
80 #define         HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST            BIT(31)
81 #define HSIO_ANA_SERDES1G_PLL_CFG               0xc0
82 #define         HSIO_ANA_SERDES1G_PLL_CFG_FSM_ENA               BIT(7)
83 #define         HSIO_ANA_SERDES1G_PLL_CFG_FSM_CTRL_DATA(x)      ((x) << 8)
84 #define         HSIO_ANA_SERDES1G_PLL_CFG_ENA_RC_DIV2           BIT(21)
85 #define HSIO_DIG_SERDES1G_DFT_CFG0              0xc8
86 #define HSIO_DIG_SERDES1G_TP_CFG                0xd4
87 #define HSIO_DIG_SERDES1G_MISC_CFG              0xdc
88 #define         HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST             BIT(0)
89 #define HSIO_MCB_SERDES1G_CFG                   0xe8
90 #define         HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT               BIT(31)
91 #define         HSIO_MCB_SERDES1G_CFG_ADDR(x)                   (x)
92
93 #define HSIO_ANA_SERDES6G_DES_CFG               0x11c
94 #define         HSIO_ANA_SERDES6G_DES_CFG_SWAP_ANA              BIT(0)
95 #define         HSIO_ANA_SERDES6G_DES_CFG_BW_ANA(x)             ((x) << 1)
96 #define         HSIO_ANA_SERDES6G_DES_CFG_SWAP_HYST             BIT(4)
97 #define         HSIO_ANA_SERDES6G_DES_CFG_BW_HYST(x)            ((x) << 5)
98 #define         HSIO_ANA_SERDES6G_DES_CFG_CPMD_SEL(x)           ((x) << 8)
99 #define         HSIO_ANA_SERDES6G_DES_CFG_MBTR_CTRL(x)          ((x) << 10)
100 #define         HSIO_ANA_SERDES6G_DES_CFG_PHS_CTRL(x)           ((x) << 13)
101 #define HSIO_ANA_SERDES6G_IB_CFG                0x120
102 #define         HSIO_ANA_SERDES6G_IB_CFG_REG_ENA                BIT(0)
103 #define         HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA                BIT(1)
104 #define         HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA                BIT(2)
105 #define         HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(x)             ((x) << 3)
106 #define         HSIO_ANA_SERDES6G_IB_CFG_CONCUR                 BIT(4)
107 #define         HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA            BIT(5)
108 #define         HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(x)     ((x) << 7)
109 #define         HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(x)      ((x) << 9)
110 #define         HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(x)     ((x) << 11)
111 #define         HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(x)      ((x) << 13)
112 #define         HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(x)     ((x) << 15)
113 #define         HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(x)       ((x) << 18)
114 #define         HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(x)            ((x) << 20)
115 #define         HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(x)            ((x) << 24)
116 #define         HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL              BIT(28)
117 #define         HSIO_ANA_SERDES6G_IB_CFG_SOFSI(x)               ((x) << 29)
118 #define HSIO_ANA_SERDES6G_IB_CFG1               0x124
119 #define         HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET           BIT(4)
120 #define         HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP               BIT(5)
121 #define         HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID              BIT(6)
122 #define         HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP               BIT(7)
123 #define         HSIO_ANA_SERDES6G_IB_CFG1_SCALY(x)              ((x) << 8)
124 #define         HSIO_ANA_SERDES6G_IB_CFG1_TSDET(x)              ((x) << 12)
125 #define         HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(x)              ((x) << 17)
126 #define HSIO_ANA_SERDES6G_IB_CFG2               0x128
127 #define         HSIO_ANA_SERDES6G_IB_CFG2_UREG(x)               (x)
128 #define         HSIO_ANA_SERDES6G_IB_CFG2_UMAX(x)               ((x) << 3)
129 #define         HSIO_ANA_SERDES6G_IB_CFG2_TCALV(x)              ((x) << 5)
130 #define         HSIO_ANA_SERDES6G_IB_CFG2_OCALS(x)              ((x) << 10)
131 #define         HSIO_ANA_SERDES6G_IB_CFG2_OINFS(x)              ((x) << 16)
132 #define         HSIO_ANA_SERDES6G_IB_CFG2_OINFI(x)              ((x) << 22)
133 #define         HSIO_ANA_SERDES6G_IB_CFG2_TINFV(x)              ((x) << 27)
134 #define HSIO_ANA_SERDES6G_IB_CFG3               0x12c
135 #define         HSIO_ANA_SERDES6G_IB_CFG3_INI_OFFSET(x)         (x)
136 #define         HSIO_ANA_SERDES6G_IB_CFG3_INI_LP(x)             ((x) << 6)
137 #define         HSIO_ANA_SERDES6G_IB_CFG3_INI_MID(x)            ((x) << 12)
138 #define         HSIO_ANA_SERDES6G_IB_CFG3_INI_HP(x)             ((x) << 18)
139 #define HSIO_ANA_SERDES6G_IB_CFG4               0x130
140 #define         HSIO_ANA_SERDES6G_IB_CFG4_MAX_OFFSET(x)         (x)
141 #define         HSIO_ANA_SERDES6G_IB_CFG4_MAX_LP(x)             ((x) << 6)
142 #define         HSIO_ANA_SERDES6G_IB_CFG4_MAX_MID(x)            ((x) << 12)
143 #define         HSIO_ANA_SERDES6G_IB_CFG4_MAX_HP(x)             ((x) << 18)
144 #define HSIO_ANA_SERDES6G_IB_CFG5               0x134
145 #define         HSIO_ANA_SERDES6G_IB_CFG4_MIN_OFFSET(x)         (x)
146 #define         HSIO_ANA_SERDES6G_IB_CFG4_MIN_LP(x)             ((x) << 6)
147 #define         HSIO_ANA_SERDES6G_IB_CFG4_MIN_MID(x)            ((x) << 12)
148 #define         HSIO_ANA_SERDES6G_IB_CFG4_MIN_HP(x)             ((x) << 18)
149 #define HSIO_ANA_SERDES6G_OB_CFG                0x138
150 #define         HSIO_ANA_SERDES6G_OB_CFG_RESISTOR_CTRL(x)       (x)
151 #define         HSIO_ANA_SERDES6G_OB_CFG_SR(x)                  ((x) << 4)
152 #define         HSIO_ANA_SERDES6G_OB_CFG_SR_H                   BIT(8)
153 #define         HSIO_ANA_SERDES6G_OB_CFG_SEL_RCTRL              BIT(9)
154 #define         HSIO_ANA_SERDES6G_OB_CFG_R_COR                  BIT(10)
155 #define         HSIO_ANA_SERDES6G_OB_CFG_POST1(x)               ((x) << 11)
156 #define         HSIO_ANA_SERDES6G_OB_CFG_R_ADJ_PDR              BIT(16)
157 #define         HSIO_ANA_SERDES6G_OB_CFG_R_ADJ_MUX              BIT(17)
158 #define         HSIO_ANA_SERDES6G_OB_CFG_PREC(x)                ((x) << 18)
159 #define         HSIO_ANA_SERDES6G_OB_CFG_POST0(x)               ((x) << 23)
160 #define         HSIO_ANA_SERDES6G_OB_CFG_POL                    BIT(29)
161 #define         HSIO_ANA_SERDES6G_OB_CFG_ENA1V_MODE(x)          ((x) << 30)
162 #define         HSIO_ANA_SERDES6G_OB_CFG_IDLE                   BIT(31)
163 #define HSIO_ANA_SERDES6G_OB_CFG1               0x13c
164 #define         HSIO_ANA_SERDES6G_OB_CFG1_LEV(x)                (x)
165 #define         HSIO_ANA_SERDES6G_OB_CFG1_ENA_CAS(x)            ((x) << 6)
166 #define HSIO_ANA_SERDES6G_SER_CFG               0x140
167 #define HSIO_ANA_SERDES6G_COMMON_CFG            0x144
168 #define         HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(x)         (x)
169 #define         HSIO_ANA_SERDES6G_COMMON_CFG_QRATE(x)           (x << 2)
170 #define         HSIO_ANA_SERDES6G_COMMON_CFG_ENA_LANE           BIT(14)
171 #define         HSIO_ANA_SERDES6G_COMMON_CFG_SYS_RST            BIT(16)
172 #define HSIO_ANA_SERDES6G_PLL_CFG               0x148
173 #define         HSIO_ANA_SERDES6G_PLL_CFG_ROT_FRQ               BIT(0)
174 #define         HSIO_ANA_SERDES6G_PLL_CFG_ROT_DIR               BIT(1)
175 #define         HSIO_ANA_SERDES6G_PLL_CFG_RB_DATA_SEL           BIT(2)
176 #define         HSIO_ANA_SERDES6G_PLL_CFG_FSM_OOR_RECAL_ENA     BIT(3)
177 #define         HSIO_ANA_SERDES6G_PLL_CFG_FSM_FORCE_SET_ENA     BIT(4)
178 #define         HSIO_ANA_SERDES6G_PLL_CFG_FSM_ENA               BIT(5)
179 #define         HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(x)      ((x) << 6)
180 #define         HSIO_ANA_SERDES6G_PLL_CFG_ENA_ROT               BIT(14)
181 #define         HSIO_ANA_SERDES6G_PLL_CFG_DIV4                  BIT(15)
182 #define         HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(x)           ((x) << 16)
183 #define HSIO_DIG_SERDES6G_MISC_CFG              0x108
184 #define         HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST             BIT(0)
185 #define HSIO_MCB_SERDES6G_CFG                   0x168
186 #define         HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT               BIT(31)
187 #define         HSIO_MCB_SERDES6G_CFG_ADDR(x)                   (x)
188 #define HSIO_HW_CFGSTAT_HW_CFG                  0x16c
189
190 #define LRN_COMMON_ACCESS_CTRL                  0x0
191 #define         LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT    BIT(0)
192 #define LRN_COMMON_MAC_ACCESS_CFG0              0x4
193 #define LRN_COMMON_MAC_ACCESS_CFG1              0x8
194 #define LRN_COMMON_MAC_ACCESS_CFG2              0xc
195 #define         LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_ADDR(x)    (x)
196 #define         LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_TYPE(x)    ((x) << 12)
197 #define         LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_VLD        BIT(15)
198 #define         LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_LOCKED     BIT(16)
199 #define         LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_COPY   BIT(23)
200 #define         LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_QU(x)  ((x) << 24)
201
202 #define QFWD_SYSTEM_SWITCH_PORT_MODE(x)         (0x4 * (x))
203 #define         QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA           BIT(17)
204
205 #define QS_XTR_GRP_CFG(x)               (0x0 + 4 * (x))
206 #define QS_INJ_GRP_CFG(x)               (0x24 + (x) * 4)
207
208 #define QSYS_SYSTEM_RESET_CFG                   0xf0
209 #define QSYS_CALCFG_CAL_AUTO(x)                 (0x3d4 + 4 * (x))
210 #define QSYS_CALCFG_CAL_CTRL                    0x3e8
211 #define         QSYS_CALCFG_CAL_CTRL_CAL_MODE(x)                ((x) << 11)
212 #define QSYS_RAM_CTRL_RAM_INIT                  0x3ec
213
214 #define REW_RAM_CTRL_RAM_INIT                   0x53528
215
216 #define VOP_RAM_CTRL_RAM_INIT                   0x43638
217
218 #define XTR_VALID_BYTES(x)      (4 - ((x) & 3))
219 #define MAC_VID                 0
220 #define CPU_PORT                53
221 #define IFH_LEN                 7
222 #define JR2_BUF_CELL_SZ         60
223 #define ETH_ALEN                6
224 #define PGID_BROADCAST          510
225 #define PGID_UNICAST            511
226
227 static const char * const regs_names[] = {
228         "port0", "port1", "port2", "port3", "port4", "port5", "port6", "port7",
229         "port8", "port9", "port10", "port11", "port12", "port13", "port14",
230         "port15", "port16", "port17", "port18", "port19", "port20", "port21",
231         "port22", "port23", "port24", "port25", "port26", "port27", "port28",
232         "port29", "port30", "port31", "port32", "port33", "port34", "port35",
233         "port36", "port37", "port38", "port39", "port40", "port41", "port42",
234         "port43", "port44", "port45", "port46", "port47",
235         "ana_ac", "ana_cl", "ana_l2", "asm", "hsio", "lrn",
236         "qfwd", "qs", "qsys", "rew",
237 };
238
239 #define REGS_NAMES_COUNT ARRAY_SIZE(regs_names) + 1
240 #define MAX_PORT 48
241
242 enum jr2_ctrl_regs {
243         ANA_AC = MAX_PORT,
244         ANA_CL,
245         ANA_L2,
246         ASM,
247         HSIO,
248         LRN,
249         QFWD,
250         QS,
251         QSYS,
252         REW,
253 };
254
255 #define JR2_MIIM_BUS_COUNT 3
256
257 struct jr2_phy_port_t {
258         size_t phy_addr;
259         struct mii_dev *bus;
260         u8 serdes_index;
261         u8 phy_mode;
262 };
263
264 struct jr2_private {
265         void __iomem *regs[REGS_NAMES_COUNT];
266         struct mii_dev *bus[JR2_MIIM_BUS_COUNT];
267         struct jr2_phy_port_t ports[MAX_PORT];
268 };
269
270 static const unsigned long jr2_regs_qs[] = {
271         [MSCC_QS_XTR_RD] = 0x8,
272         [MSCC_QS_XTR_FLUSH] = 0x18,
273         [MSCC_QS_XTR_DATA_PRESENT] = 0x1c,
274         [MSCC_QS_INJ_WR] = 0x2c,
275         [MSCC_QS_INJ_CTRL] = 0x34,
276 };
277
278 static struct mscc_miim_dev miim[JR2_MIIM_BUS_COUNT];
279 static int miim_count = -1;
280
281 static void jr2_cpu_capture_setup(struct jr2_private *priv)
282 {
283         /* ASM: No preamble and IFH prefix on CPU injected frames */
284         writel(ASM_CFG_PORT_NO_PREAMBLE_ENA |
285                ASM_CFG_PORT_INJ_FORMAT_CFG(1),
286                priv->regs[ASM] + ASM_CFG_PORT(CPU_PORT));
287
288         /* Set Manual injection via DEVCPU_QS registers for CPU queue 0 */
289         writel(0x5, priv->regs[QS] + QS_INJ_GRP_CFG(0));
290
291         /* Set Manual extraction via DEVCPU_QS registers for CPU queue 0 */
292         writel(0x7, priv->regs[QS] + QS_XTR_GRP_CFG(0));
293
294         /* Enable CPU port for any frame transfer */
295         setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(CPU_PORT),
296                      QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA);
297
298         /* Send a copy to CPU when found as forwarding entry */
299         setbits_le32(priv->regs[ANA_L2] + ANA_L2_COMMON_FWD_CFG,
300                      ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA);
301 }
302
303 static void jr2_port_init(struct jr2_private *priv, int port)
304 {
305         void __iomem *regs = priv->regs[port];
306
307         /* Enable PCS */
308         writel(DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA,
309                regs + DEV_PCS1G_CFG_PCS1G_CFG);
310
311         /* Disable Signal Detect */
312         writel(0, regs + DEV_PCS1G_CFG_PCS1G_SD);
313
314         /* Enable MAC RX and TX */
315         writel(DEV_MAC_CFG_MAC_ENA_RX_ENA |
316                DEV_MAC_CFG_MAC_ENA_TX_ENA,
317                regs + DEV_MAC_CFG_MAC_ENA);
318
319         /* Clear sgmii_mode_ena */
320         writel(0, regs + DEV_PCS1G_CFG_PCS1G_MODE);
321
322         /*
323          * Clear sw_resolve_ena(bit 0) and set adv_ability to
324          * something meaningful just in case
325          */
326         writel(DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(0x20),
327                regs + DEV_PCS1G_CFG_PCS1G_ANEG);
328
329         /* Set MAC IFG Gaps */
330         writel(DEV_MAC_CFG_MAC_IFG_TX_IFG(4) |
331                DEV_MAC_CFG_MAC_IFG_RX_IFG1(5) |
332                DEV_MAC_CFG_MAC_IFG_RX_IFG2(1),
333                regs + DEV_MAC_CFG_MAC_IFG);
334
335         /* Set link speed and release all resets */
336         writel(DEV_DEV_CFG_DEV_RST_CTRL_SPEED_SEL(2),
337                regs + DEV_DEV_CFG_DEV_RST_CTRL);
338
339         /* Make VLAN aware for CPU traffic */
340         writel(ANA_CL_PORT_VLAN_CFG_AWARE_ENA |
341                ANA_CL_PORT_VLAN_CFG_POP_CNT(1) |
342                MAC_VID,
343                priv->regs[ANA_CL] + ANA_CL_PORT_VLAN_CFG(port));
344
345         /* Enable CPU port for any frame transfer */
346         setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(port),
347                      QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA);
348 }
349
350 static void serdes6g_write(void __iomem *base, u32 addr)
351 {
352         u32 data;
353
354         writel(HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT |
355                HSIO_MCB_SERDES6G_CFG_ADDR(addr),
356                base + HSIO_MCB_SERDES6G_CFG);
357
358         do {
359                 data = readl(base + HSIO_MCB_SERDES6G_CFG);
360         } while (data & HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT);
361 }
362
363 static void serdes6g_setup(void __iomem *base, uint32_t addr,
364                            phy_interface_t interface)
365 {
366         u32 ib_if_mode = 0;
367         u32 ib_qrate = 0;
368         u32 ib_cal_ena = 0;
369         u32 ib1_tsdet = 0;
370         u32 ob_lev = 0;
371         u32 ob_ena_cas = 0;
372         u32 ob_ena1v_mode = 0;
373         u32 des_bw_ana = 0;
374         u32 pll_fsm_ctrl_data = 0;
375
376         switch (interface) {
377         case PHY_INTERFACE_MODE_SGMII:
378                 ib_if_mode = 1;
379                 ib_qrate = 1;
380                 ib_cal_ena = 1;
381                 ib1_tsdet = 3;
382                 ob_lev = 48;
383                 ob_ena_cas = 2;
384                 ob_ena1v_mode = 1;
385                 des_bw_ana = 3;
386                 pll_fsm_ctrl_data = 60;
387                 break;
388         case PHY_INTERFACE_MODE_QSGMII:
389                 ib_if_mode = 3;
390                 ib1_tsdet = 16;
391                 ob_lev = 24;
392                 des_bw_ana = 5;
393                 pll_fsm_ctrl_data = 120;
394                 break;
395         default:
396                 pr_err("Interface not supported\n");
397                 return;
398         }
399
400         if (interface == PHY_INTERFACE_MODE_QSGMII)
401                 writel(0xfff, base + HSIO_HW_CFGSTAT_HW_CFG);
402
403         writel(HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(3),
404                base + HSIO_ANA_SERDES6G_COMMON_CFG);
405         writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(120) |
406                HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
407                base + HSIO_ANA_SERDES6G_PLL_CFG);
408         writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
409                HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
410                HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
411                HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
412                HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
413                HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
414                HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
415                HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
416                HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
417                HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(7) |
418                HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
419                HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
420                HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
421                HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
422                HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
423                base + HSIO_ANA_SERDES6G_IB_CFG);
424         writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
425                HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
426                HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
427                HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
428                HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
429                HSIO_ANA_SERDES6G_IB_CFG1_TSDET(3) |
430                HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
431                base + HSIO_ANA_SERDES6G_IB_CFG1);
432         writel(HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST,
433                base + HSIO_DIG_SERDES6G_MISC_CFG);
434
435         serdes6g_write(base, addr);
436
437         writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
438                HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
439                HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
440                HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
441                HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
442                HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
443                HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
444                HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
445                HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
446                HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(0) |
447                HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
448                HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
449                HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
450                HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
451                HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
452                base + HSIO_ANA_SERDES6G_IB_CFG);
453         writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
454                HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
455                HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
456                HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
457                HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
458                HSIO_ANA_SERDES6G_IB_CFG1_TSDET(16) |
459                HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
460                base + HSIO_ANA_SERDES6G_IB_CFG1);
461
462         writel(0x0, base + HSIO_ANA_SERDES6G_SER_CFG);
463         writel(HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(ib_if_mode) |
464                HSIO_ANA_SERDES6G_COMMON_CFG_QRATE(ib_qrate) |
465                HSIO_ANA_SERDES6G_COMMON_CFG_ENA_LANE |
466                HSIO_ANA_SERDES6G_COMMON_CFG_SYS_RST,
467                base + HSIO_ANA_SERDES6G_COMMON_CFG);
468         writel(HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST,
469                base + HSIO_DIG_SERDES6G_MISC_CFG);
470
471         writel(HSIO_ANA_SERDES6G_OB_CFG_RESISTOR_CTRL(1) |
472                HSIO_ANA_SERDES6G_OB_CFG_SR(7) |
473                HSIO_ANA_SERDES6G_OB_CFG_SR_H |
474                HSIO_ANA_SERDES6G_OB_CFG_ENA1V_MODE(ob_ena1v_mode) |
475                HSIO_ANA_SERDES6G_OB_CFG_POL, base + HSIO_ANA_SERDES6G_OB_CFG);
476         writel(HSIO_ANA_SERDES6G_OB_CFG1_LEV(ob_lev) |
477                HSIO_ANA_SERDES6G_OB_CFG1_ENA_CAS(ob_ena_cas),
478                base + HSIO_ANA_SERDES6G_OB_CFG1);
479
480         writel(HSIO_ANA_SERDES6G_DES_CFG_BW_ANA(des_bw_ana) |
481                HSIO_ANA_SERDES6G_DES_CFG_BW_HYST(5) |
482                HSIO_ANA_SERDES6G_DES_CFG_MBTR_CTRL(2) |
483                HSIO_ANA_SERDES6G_DES_CFG_PHS_CTRL(6),
484                base + HSIO_ANA_SERDES6G_DES_CFG);
485         writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(pll_fsm_ctrl_data) |
486                HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
487                base + HSIO_ANA_SERDES6G_PLL_CFG);
488
489         serdes6g_write(base, addr);
490
491         /* set pll_fsm_ena = 1 */
492         writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_ENA |
493                HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(pll_fsm_ctrl_data) |
494                HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
495                base + HSIO_ANA_SERDES6G_PLL_CFG);
496
497         serdes6g_write(base, addr);
498
499         /* wait 20ms for pll bringup */
500         mdelay(20);
501
502         /* start IB calibration by setting ib_cal_ena and clearing lane_rst */
503         writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
504                HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
505                HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
506                HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(ib_cal_ena) |
507                HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
508                HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
509                HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
510                HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
511                HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
512                HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
513                HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(0) |
514                HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
515                HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
516                HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
517                HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
518                HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
519                base + HSIO_ANA_SERDES6G_IB_CFG);
520         writel(0x0, base + HSIO_DIG_SERDES6G_MISC_CFG);
521
522         serdes6g_write(base, addr);
523
524         /* wait 60 for calibration */
525         mdelay(60);
526
527         /* set ib_tsdet and ib_reg_pat_sel_offset back to correct values */
528         writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
529                HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
530                HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
531                HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(ib_cal_ena) |
532                HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
533                HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
534                HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
535                HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
536                HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
537                HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
538                HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(7) |
539                HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
540                HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
541                HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
542                HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
543                HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
544                base + HSIO_ANA_SERDES6G_IB_CFG);
545         writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
546                HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
547                HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
548                HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
549                HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
550                HSIO_ANA_SERDES6G_IB_CFG1_TSDET(ib1_tsdet) |
551                HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
552                base + HSIO_ANA_SERDES6G_IB_CFG1);
553
554         serdes6g_write(base, addr);
555 }
556
557 static void serdes1g_write(void __iomem *base, u32 addr)
558 {
559         u32 data;
560
561         writel(HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT |
562                HSIO_MCB_SERDES1G_CFG_ADDR(addr),
563                base + HSIO_MCB_SERDES1G_CFG);
564
565         do {
566                 data = readl(base + HSIO_MCB_SERDES1G_CFG);
567         } while (data & HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT);
568 }
569
570 static void serdes1g_setup(void __iomem *base, uint32_t addr,
571                            phy_interface_t interface)
572 {
573         writel(0x0, base + HSIO_ANA_SERDES1G_SER_CFG);
574         writel(0x0, base + HSIO_DIG_SERDES1G_TP_CFG);
575         writel(0x0, base + HSIO_DIG_SERDES1G_DFT_CFG0);
576         writel(HSIO_ANA_SERDES1G_OB_CFG_RESISTOR_CTRL(1) |
577                HSIO_ANA_SERDES1G_OB_CFG_VCM_CTRL(4) |
578                HSIO_ANA_SERDES1G_OB_CFG_CMM_BIAS_CTRL(2) |
579                HSIO_ANA_SERDES1G_OB_CFG_AMP_CTRL(12) |
580                HSIO_ANA_SERDES1G_OB_CFG_SLP(3),
581                base + HSIO_ANA_SERDES1G_OB_CFG);
582         writel(HSIO_ANA_SERDES1G_IB_CFG_RESISTOR_CTRL(13) |
583                HSIO_ANA_SERDES1G_IB_CFG_EQ_GAIN(2) |
584                HSIO_ANA_SERDES1G_IB_CFG_ENA_OFFSET_COMP |
585                HSIO_ANA_SERDES1G_IB_CFG_ENA_DETLEV |
586                HSIO_ANA_SERDES1G_IB_CFG_ENA_CMV_TERM |
587                HSIO_ANA_SERDES1G_IB_CFG_DET_LEV(3) |
588                HSIO_ANA_SERDES1G_IB_CFG_ACJTAG_HYST(1),
589                base + HSIO_ANA_SERDES1G_IB_CFG);
590         writel(HSIO_ANA_SERDES1G_DES_CFG_BW_HYST(7) |
591                HSIO_ANA_SERDES1G_DES_CFG_BW_ANA(6) |
592                HSIO_ANA_SERDES1G_DES_CFG_MBTR_CTRL(2) |
593                HSIO_ANA_SERDES1G_DES_CFG_PHS_CTRL(6),
594                base + HSIO_ANA_SERDES1G_DES_CFG);
595         writel(HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST,
596                base + HSIO_DIG_SERDES1G_MISC_CFG);
597         writel(HSIO_ANA_SERDES1G_PLL_CFG_FSM_ENA |
598                HSIO_ANA_SERDES1G_PLL_CFG_FSM_CTRL_DATA(0xc8) |
599                HSIO_ANA_SERDES1G_PLL_CFG_ENA_RC_DIV2,
600                base + HSIO_ANA_SERDES1G_PLL_CFG);
601         writel(HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE |
602                HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE |
603                HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST,
604                base + HSIO_ANA_SERDES1G_COMMON_CFG);
605
606         serdes1g_write(base, addr);
607
608         setbits_le32(base + HSIO_ANA_SERDES1G_COMMON_CFG,
609                      HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST);
610
611         serdes1g_write(base, addr);
612
613         clrbits_le32(base + HSIO_DIG_SERDES1G_MISC_CFG,
614                      HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST);
615
616         serdes1g_write(base, addr);
617 }
618
619 static int ram_init(u32 val, void __iomem *addr)
620 {
621         writel(val, addr);
622
623         if (wait_for_bit_le32(addr, BIT(1), false, 2000, false)) {
624                 printf("Timeout in memory reset, reg = 0x%08x\n", val);
625                 return 1;
626         }
627
628         return 0;
629 }
630
631 static int jr2_switch_init(struct jr2_private *priv)
632 {
633         /* Initialize memories */
634         ram_init(0x3, priv->regs[QSYS] + QSYS_RAM_CTRL_RAM_INIT);
635         ram_init(0x3, priv->regs[ASM] + ASM_RAM_CTRL_RAM_INIT);
636         ram_init(0x3, priv->regs[ANA_AC] + ANA_AC_RAM_CTRL_RAM_INIT);
637         ram_init(0x3, priv->regs[REW] + REW_RAM_CTRL_RAM_INIT);
638
639         /* Reset counters */
640         writel(0x1, priv->regs[ANA_AC] + ANA_AC_STAT_GLOBAL_CFG_PORT_RESET);
641         writel(0x1, priv->regs[ASM] + ASM_CFG_STAT_CFG);
642
643         /* Enable switch-core and queue system */
644         writel(0x1, priv->regs[QSYS] + QSYS_SYSTEM_RESET_CFG);
645
646         return 0;
647 }
648
649 static void jr2_switch_config(struct jr2_private *priv)
650 {
651         writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(0));
652         writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(1));
653         writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(2));
654         writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(3));
655
656         writel(readl(priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL) |
657                QSYS_CALCFG_CAL_CTRL_CAL_MODE(8),
658                priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL);
659 }
660
661 static int jr2_initialize(struct jr2_private *priv)
662 {
663         int ret, i;
664
665         /* Initialize switch memories, enable core */
666         ret = jr2_switch_init(priv);
667         if (ret)
668                 return ret;
669
670         jr2_switch_config(priv);
671
672         for (i = 0; i < MAX_PORT; i++)
673                 jr2_port_init(priv, i);
674
675         jr2_cpu_capture_setup(priv);
676
677         return 0;
678 }
679
680 static inline int jr2_vlant_wait_for_completion(struct jr2_private *priv)
681 {
682         if (wait_for_bit_le32(priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL,
683                               LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
684                               false, 2000, false))
685                 return -ETIMEDOUT;
686
687         return 0;
688 }
689
690 static int jr2_mac_table_add(struct jr2_private *priv,
691                              const unsigned char mac[ETH_ALEN], int pgid)
692 {
693         u32 macl = 0, mach = 0;
694
695         /*
696          * Set the MAC address to handle and the vlan associated in a format
697          * understood by the hardware.
698          */
699         mach |= MAC_VID << 16;
700         mach |= ((u32)mac[0]) << 8;
701         mach |= ((u32)mac[1]) << 0;
702         macl |= ((u32)mac[2]) << 24;
703         macl |= ((u32)mac[3]) << 16;
704         macl |= ((u32)mac[4]) << 8;
705         macl |= ((u32)mac[5]) << 0;
706
707         writel(mach, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG0);
708         writel(macl, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG1);
709
710         writel(LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_ADDR(pgid) |
711                LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_TYPE(0x3) |
712                LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_COPY |
713                LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_QU(0) |
714                LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_VLD |
715                LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_LOCKED,
716                priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG2);
717
718         writel(LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
719                priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL);
720
721         return jr2_vlant_wait_for_completion(priv);
722 }
723
724 static int jr2_write_hwaddr(struct udevice *dev)
725 {
726         struct jr2_private *priv = dev_get_priv(dev);
727         struct eth_pdata *pdata = dev_get_platdata(dev);
728
729         return jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
730 }
731
732 static void serdes_setup(struct jr2_private *priv)
733 {
734         size_t mask;
735         int i = 0;
736
737         for (i = 0; i < MAX_PORT; ++i) {
738                 if (!priv->ports[i].bus || priv->ports[i].serdes_index == 0xff)
739                         continue;
740
741                 mask = BIT(priv->ports[i].serdes_index);
742                 if (priv->ports[i].serdes_index < SERDES1G_MAX) {
743                         serdes1g_setup(priv->regs[HSIO], mask,
744                                        priv->ports[i].phy_mode);
745                 } else {
746                         mask >>= SERDES6G(0);
747                         serdes6g_setup(priv->regs[HSIO], mask,
748                                        priv->ports[i].phy_mode);
749                 }
750         }
751 }
752
753 static int jr2_start(struct udevice *dev)
754 {
755         struct jr2_private *priv = dev_get_priv(dev);
756         struct eth_pdata *pdata = dev_get_platdata(dev);
757         const unsigned char mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff,
758                 0xff };
759         int ret;
760
761         ret = jr2_initialize(priv);
762         if (ret)
763                 return ret;
764
765         /* Set MAC address tables entries for CPU redirection */
766         ret = jr2_mac_table_add(priv, mac, PGID_BROADCAST);
767         if (ret)
768                 return ret;
769
770         ret = jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
771         if (ret)
772                 return ret;
773
774         serdes_setup(priv);
775
776         return 0;
777 }
778
779 static void jr2_stop(struct udevice *dev)
780 {
781 }
782
783 static int jr2_send(struct udevice *dev, void *packet, int length)
784 {
785         struct jr2_private *priv = dev_get_priv(dev);
786         u32 ifh[IFH_LEN];
787         u32 *buf = packet;
788
789         memset(ifh, '\0', IFH_LEN);
790
791         /* Set DST PORT_MASK */
792         ifh[0] = htonl(0);
793         ifh[1] = htonl(0x1FFFFF);
794         ifh[2] = htonl(~0);
795         /* Set DST_MODE to INJECT and UPDATE_FCS */
796         ifh[5] = htonl(0x4c0);
797
798         return mscc_send(priv->regs[QS], jr2_regs_qs,
799                          ifh, IFH_LEN, buf, length);
800 }
801
802 static int jr2_recv(struct udevice *dev, int flags, uchar **packetp)
803 {
804         struct jr2_private *priv = dev_get_priv(dev);
805         u32 *rxbuf = (u32 *)net_rx_packets[0];
806         int byte_cnt = 0;
807
808         byte_cnt = mscc_recv(priv->regs[QS], jr2_regs_qs, rxbuf, IFH_LEN,
809                              false);
810
811         *packetp = net_rx_packets[0];
812
813         return byte_cnt;
814 }
815
816 static struct mii_dev *get_mdiobus(phys_addr_t base, unsigned long size)
817 {
818         int i = 0;
819
820         for (i = 0; i < JR2_MIIM_BUS_COUNT; ++i)
821                 if (miim[i].miim_base == base && miim[i].miim_size == size)
822                         return miim[i].bus;
823
824         return NULL;
825 }
826
827 static void add_port_entry(struct jr2_private *priv, size_t index,
828                            size_t phy_addr, struct mii_dev *bus,
829                            u8 serdes_index, u8 phy_mode)
830 {
831         priv->ports[index].phy_addr = phy_addr;
832         priv->ports[index].bus = bus;
833         priv->ports[index].serdes_index = serdes_index;
834         priv->ports[index].phy_mode = phy_mode;
835 }
836
837 static int jr2_probe(struct udevice *dev)
838 {
839         struct jr2_private *priv = dev_get_priv(dev);
840         int i;
841         int ret;
842         struct resource res;
843         fdt32_t faddr;
844         phys_addr_t addr_base;
845         unsigned long addr_size;
846         ofnode eth_node, node, mdio_node;
847         size_t phy_addr;
848         struct mii_dev *bus;
849         struct ofnode_phandle_args phandle;
850         struct phy_device *phy;
851
852         if (!priv)
853                 return -EINVAL;
854
855         /* Get registers and map them to the private structure */
856         for (i = 0; i < ARRAY_SIZE(regs_names); i++) {
857                 priv->regs[i] = dev_remap_addr_name(dev, regs_names[i]);
858                 if (!priv->regs[i]) {
859                         debug
860                             ("Error can't get regs base addresses for %s\n",
861                              regs_names[i]);
862                         return -ENOMEM;
863                 }
864         }
865
866         /* Initialize miim buses */
867         memset(&miim, 0x0, sizeof(struct mscc_miim_dev) * JR2_MIIM_BUS_COUNT);
868
869         /* iterate all the ports and find out on which bus they are */
870         i = 0;
871         eth_node = dev_read_first_subnode(dev);
872         for (node = ofnode_first_subnode(eth_node);
873              ofnode_valid(node);
874              node = ofnode_next_subnode(node)) {
875                 if (ofnode_read_resource(node, 0, &res))
876                         return -ENOMEM;
877                 i = res.start;
878
879                 ret = ofnode_parse_phandle_with_args(node, "phy-handle", NULL,
880                                                      0, 0, &phandle);
881                 if (ret)
882                         continue;
883
884                 /* Get phy address on mdio bus */
885                 if (ofnode_read_resource(phandle.node, 0, &res))
886                         return -ENOMEM;
887                 phy_addr = res.start;
888
889                 /* Get mdio node */
890                 mdio_node = ofnode_get_parent(phandle.node);
891
892                 if (ofnode_read_resource(mdio_node, 0, &res))
893                         return -ENOMEM;
894                 faddr = cpu_to_fdt32(res.start);
895
896                 addr_base = ofnode_translate_address(mdio_node, &faddr);
897                 addr_size = res.end - res.start;
898
899                 /* If the bus is new then create a new bus */
900                 if (!get_mdiobus(addr_base, addr_size))
901                         priv->bus[miim_count] =
902                                 mscc_mdiobus_init(miim, &miim_count, addr_base,
903                                                   addr_size);
904
905                 /* Connect mdio bus with the port */
906                 bus = get_mdiobus(addr_base, addr_size);
907
908                 /* Get serdes info */
909                 ret = ofnode_parse_phandle_with_args(node, "phys", NULL,
910                                                      3, 0, &phandle);
911                 if (ret)
912                         return -ENOMEM;
913
914                 add_port_entry(priv, i, phy_addr, bus, phandle.args[1],
915                                phandle.args[2]);
916         }
917
918         for (i = 0; i < MAX_PORT; i++) {
919                 if (!priv->ports[i].bus)
920                         continue;
921
922                 phy = phy_connect(priv->ports[i].bus,
923                                   priv->ports[i].phy_addr, dev,
924                                   PHY_INTERFACE_MODE_NONE);
925                 if (phy)
926                         board_phy_config(phy);
927         }
928
929         return 0;
930 }
931
932 static int jr2_remove(struct udevice *dev)
933 {
934         struct jr2_private *priv = dev_get_priv(dev);
935         int i;
936
937         for (i = 0; i < JR2_MIIM_BUS_COUNT; i++) {
938                 mdio_unregister(priv->bus[i]);
939                 mdio_free(priv->bus[i]);
940         }
941
942         return 0;
943 }
944
945 static const struct eth_ops jr2_ops = {
946         .start        = jr2_start,
947         .stop         = jr2_stop,
948         .send         = jr2_send,
949         .recv         = jr2_recv,
950         .write_hwaddr = jr2_write_hwaddr,
951 };
952
953 static const struct udevice_id mscc_jr2_ids[] = {
954         {.compatible = "mscc,vsc7454-switch" },
955         { /* Sentinel */ }
956 };
957
958 U_BOOT_DRIVER(jr2) = {
959         .name                           = "jr2-switch",
960         .id                             = UCLASS_ETH,
961         .of_match                       = mscc_jr2_ids,
962         .probe                          = jr2_probe,
963         .remove                         = jr2_remove,
964         .ops                            = &jr2_ops,
965         .priv_auto_alloc_size           = sizeof(struct jr2_private),
966         .platdata_auto_alloc_size       = sizeof(struct eth_pdata),
967 };