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