1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
3 * Copyright (c) 2018 Microsemi Corporation
9 #include <dm/of_access.h>
10 #include <dm/of_addr.h>
11 #include <fdt_support.h>
13 #include <linux/ioport.h>
18 #include <dt-bindings/mscc/jr2_data.h>
19 #include "mscc_xfer.h"
20 #include "mscc_miim.h"
22 #define ANA_AC_RAM_CTRL_RAM_INIT 0x94358
23 #define ANA_AC_STAT_GLOBAL_CFG_PORT_RESET 0x94370
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)
29 #define ANA_L2_COMMON_FWD_CFG 0x8a2a8
30 #define ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA BIT(6)
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
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)
54 #define DSM_RAM_CTRL_RAM_INIT 0x8
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)
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
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)
201 #define QFWD_SYSTEM_SWITCH_PORT_MODE(x) (0x4 * (x))
202 #define QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA BIT(17)
204 #define QS_XTR_GRP_CFG(x) (0x0 + 4 * (x))
205 #define QS_INJ_GRP_CFG(x) (0x24 + (x) * 4)
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
213 #define REW_RAM_CTRL_RAM_INIT 0x53528
215 #define VOP_RAM_CTRL_RAM_INIT 0x43638
217 #define XTR_VALID_BYTES(x) (4 - ((x) & 3))
221 #define JR2_BUF_CELL_SZ 60
223 #define PGID_BROADCAST 510
224 #define PGID_UNICAST 511
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",
238 #define REGS_NAMES_COUNT ARRAY_SIZE(regs_names) + 1
254 #define JR2_MIIM_BUS_COUNT 3
256 struct jr2_phy_port_t {
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];
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,
277 static struct mscc_miim_dev miim[JR2_MIIM_BUS_COUNT];
278 static int miim_count = -1;
280 static void jr2_cpu_capture_setup(struct jr2_private *priv)
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));
287 /* Set Manual injection via DEVCPU_QS registers for CPU queue 0 */
288 writel(0x5, priv->regs[QS] + QS_INJ_GRP_CFG(0));
290 /* Set Manual extraction via DEVCPU_QS registers for CPU queue 0 */
291 writel(0x7, priv->regs[QS] + QS_XTR_GRP_CFG(0));
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);
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);
302 static void jr2_port_init(struct jr2_private *priv, int port)
304 void __iomem *regs = priv->regs[port];
307 writel(DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA,
308 regs + DEV_PCS1G_CFG_PCS1G_CFG);
310 /* Disable Signal Detect */
311 writel(0, regs + DEV_PCS1G_CFG_PCS1G_SD);
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);
318 /* Clear sgmii_mode_ena */
319 writel(0, regs + DEV_PCS1G_CFG_PCS1G_MODE);
322 * Clear sw_resolve_ena(bit 0) and set adv_ability to
323 * something meaningful just in case
325 writel(DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(0x20),
326 regs + DEV_PCS1G_CFG_PCS1G_ANEG);
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);
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);
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) |
342 priv->regs[ANA_CL] + ANA_CL_PORT_VLAN_CFG(port));
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);
349 static void serdes6g_write(void __iomem *base, u32 addr)
353 writel(HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT |
354 HSIO_MCB_SERDES6G_CFG_ADDR(addr),
355 base + HSIO_MCB_SERDES6G_CFG);
358 data = readl(base + HSIO_MCB_SERDES6G_CFG);
359 } while (data & HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT);
362 static void serdes6g_setup(void __iomem *base, uint32_t addr,
363 phy_interface_t interface)
371 u32 ob_ena1v_mode = 0;
373 u32 pll_fsm_ctrl_data = 0;
376 case PHY_INTERFACE_MODE_SGMII:
385 pll_fsm_ctrl_data = 60;
387 case PHY_INTERFACE_MODE_QSGMII:
392 pll_fsm_ctrl_data = 120;
395 pr_err("Interface not supported\n");
399 if (interface == PHY_INTERFACE_MODE_QSGMII)
400 writel(0xfff, base + HSIO_HW_CFGSTAT_HW_CFG);
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);
434 serdes6g_write(base, addr);
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);
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);
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);
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);
488 serdes6g_write(base, addr);
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);
496 serdes6g_write(base, addr);
498 /* wait 20ms for pll bringup */
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);
521 serdes6g_write(base, addr);
523 /* wait 60 for calibration */
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);
553 serdes6g_write(base, addr);
556 static void serdes1g_write(void __iomem *base, u32 addr)
560 writel(HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT |
561 HSIO_MCB_SERDES1G_CFG_ADDR(addr),
562 base + HSIO_MCB_SERDES1G_CFG);
565 data = readl(base + HSIO_MCB_SERDES1G_CFG);
566 } while (data & HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT);
569 static void serdes1g_setup(void __iomem *base, uint32_t addr,
570 phy_interface_t interface)
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);
605 serdes1g_write(base, addr);
607 setbits_le32(base + HSIO_ANA_SERDES1G_COMMON_CFG,
608 HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST);
610 serdes1g_write(base, addr);
612 clrbits_le32(base + HSIO_DIG_SERDES1G_MISC_CFG,
613 HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST);
615 serdes1g_write(base, addr);
618 static int ram_init(u32 val, void __iomem *addr)
622 if (wait_for_bit_le32(addr, BIT(1), false, 2000, false)) {
623 printf("Timeout in memory reset, reg = 0x%08x\n", val);
630 static int jr2_switch_init(struct jr2_private *priv)
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);
639 writel(0x1, priv->regs[ANA_AC] + ANA_AC_STAT_GLOBAL_CFG_PORT_RESET);
640 writel(0x1, priv->regs[ASM] + ASM_CFG_STAT_CFG);
642 /* Enable switch-core and queue system */
643 writel(0x1, priv->regs[QSYS] + QSYS_SYSTEM_RESET_CFG);
648 static void jr2_switch_config(struct jr2_private *priv)
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));
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);
660 static int jr2_initialize(struct jr2_private *priv)
664 /* Initialize switch memories, enable core */
665 ret = jr2_switch_init(priv);
669 jr2_switch_config(priv);
671 for (i = 0; i < MAX_PORT; i++)
672 jr2_port_init(priv, i);
674 jr2_cpu_capture_setup(priv);
679 static inline int jr2_vlant_wait_for_completion(struct jr2_private *priv)
681 if (wait_for_bit_le32(priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL,
682 LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
689 static int jr2_mac_table_add(struct jr2_private *priv,
690 const unsigned char mac[ETH_ALEN], int pgid)
692 u32 macl = 0, mach = 0;
695 * Set the MAC address to handle and the vlan associated in a format
696 * understood by the hardware.
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;
706 writel(mach, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG0);
707 writel(macl, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG1);
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);
717 writel(LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
718 priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL);
720 return jr2_vlant_wait_for_completion(priv);
723 static int jr2_write_hwaddr(struct udevice *dev)
725 struct jr2_private *priv = dev_get_priv(dev);
726 struct eth_pdata *pdata = dev_get_platdata(dev);
728 return jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
731 static void serdes_setup(struct jr2_private *priv)
736 for (i = 0; i < MAX_PORT; ++i) {
737 if (!priv->ports[i].bus || priv->ports[i].serdes_index == 0xff)
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);
745 mask >>= SERDES6G(0);
746 serdes6g_setup(priv->regs[HSIO], mask,
747 priv->ports[i].phy_mode);
752 static int jr2_start(struct udevice *dev)
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,
760 ret = jr2_initialize(priv);
764 /* Set MAC address tables entries for CPU redirection */
765 ret = jr2_mac_table_add(priv, mac, PGID_BROADCAST);
769 ret = jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
778 static void jr2_stop(struct udevice *dev)
782 static int jr2_send(struct udevice *dev, void *packet, int length)
784 struct jr2_private *priv = dev_get_priv(dev);
788 memset(ifh, '\0', IFH_LEN);
790 /* Set DST PORT_MASK */
792 ifh[1] = htonl(0x1FFFFF);
794 /* Set DST_MODE to INJECT and UPDATE_FCS */
795 ifh[5] = htonl(0x4c0);
797 return mscc_send(priv->regs[QS], jr2_regs_qs,
798 ifh, IFH_LEN, buf, length);
801 static int jr2_recv(struct udevice *dev, int flags, uchar **packetp)
803 struct jr2_private *priv = dev_get_priv(dev);
804 u32 *rxbuf = (u32 *)net_rx_packets[0];
807 byte_cnt = mscc_recv(priv->regs[QS], jr2_regs_qs, rxbuf, IFH_LEN,
810 *packetp = net_rx_packets[0];
815 static struct mii_dev *get_mdiobus(phys_addr_t base, unsigned long size)
819 for (i = 0; i < JR2_MIIM_BUS_COUNT; ++i)
820 if (miim[i].miim_base == base && miim[i].miim_size == size)
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)
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;
836 static int jr2_probe(struct udevice *dev)
838 struct jr2_private *priv = dev_get_priv(dev);
843 phys_addr_t addr_base;
844 unsigned long addr_size;
845 ofnode eth_node, node, mdio_node;
848 struct ofnode_phandle_args phandle;
849 struct phy_device *phy;
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]) {
859 ("Error can't get regs base addresses for %s\n",
865 /* Initialize miim buses */
866 memset(&miim, 0x0, sizeof(struct mscc_miim_dev) * JR2_MIIM_BUS_COUNT);
868 /* iterate all the ports and find out on which bus they are */
870 eth_node = dev_read_first_subnode(dev);
871 for (node = ofnode_first_subnode(eth_node);
873 node = ofnode_next_subnode(node)) {
874 if (ofnode_read_resource(node, 0, &res))
878 ret = ofnode_parse_phandle_with_args(node, "phy-handle", NULL,
883 /* Get phy address on mdio bus */
884 if (ofnode_read_resource(phandle.node, 0, &res))
886 phy_addr = res.start;
889 mdio_node = ofnode_get_parent(phandle.node);
891 if (ofnode_read_resource(mdio_node, 0, &res))
893 faddr = cpu_to_fdt32(res.start);
895 addr_base = ofnode_translate_address(mdio_node, &faddr);
896 addr_size = res.end - res.start;
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,
904 /* Connect mdio bus with the port */
905 bus = get_mdiobus(addr_base, addr_size);
907 /* Get serdes info */
908 ret = ofnode_parse_phandle_with_args(node, "phys", NULL,
913 add_port_entry(priv, i, phy_addr, bus, phandle.args[1],
917 for (i = 0; i < MAX_PORT; i++) {
918 if (!priv->ports[i].bus)
921 phy = phy_connect(priv->ports[i].bus,
922 priv->ports[i].phy_addr, dev,
923 PHY_INTERFACE_MODE_NONE);
925 board_phy_config(phy);
931 static int jr2_remove(struct udevice *dev)
933 struct jr2_private *priv = dev_get_priv(dev);
936 for (i = 0; i < JR2_MIIM_BUS_COUNT; i++) {
937 mdio_unregister(priv->bus[i]);
938 mdio_free(priv->bus[i]);
944 static const struct eth_ops jr2_ops = {
949 .write_hwaddr = jr2_write_hwaddr,
952 static const struct udevice_id mscc_jr2_ids[] = {
953 {.compatible = "mscc,vsc7454-switch" },
957 U_BOOT_DRIVER(jr2) = {
958 .name = "jr2-switch",
960 .of_match = mscc_jr2_ids,
962 .remove = jr2_remove,
964 .priv_auto_alloc_size = sizeof(struct jr2_private),
965 .platdata_auto_alloc_size = sizeof(struct eth_pdata),