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