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