1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
3 * Copyright (c) 2018 Microsemi Corporation
10 #include <dm/of_access.h>
11 #include <dm/of_addr.h>
12 #include <fdt_support.h>
13 #include <linux/delay.h>
15 #include <linux/ioport.h>
20 #include <dt-bindings/mscc/jr2_data.h>
21 #include "mscc_xfer.h"
22 #include "mscc_miim.h"
24 #define ANA_AC_RAM_CTRL_RAM_INIT 0x94358
25 #define ANA_AC_STAT_GLOBAL_CFG_PORT_RESET 0x94370
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)
31 #define ANA_L2_COMMON_FWD_CFG 0x8a2a8
32 #define ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA BIT(6)
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
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)
56 #define DSM_RAM_CTRL_RAM_INIT 0x8
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)
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
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)
203 #define QFWD_SYSTEM_SWITCH_PORT_MODE(x) (0x4 * (x))
204 #define QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA BIT(17)
206 #define QS_XTR_GRP_CFG(x) (0x0 + 4 * (x))
207 #define QS_INJ_GRP_CFG(x) (0x24 + (x) * 4)
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
215 #define REW_RAM_CTRL_RAM_INIT 0x53528
217 #define VOP_RAM_CTRL_RAM_INIT 0x43638
219 #define XTR_VALID_BYTES(x) (4 - ((x) & 3))
223 #define JR2_BUF_CELL_SZ 60
225 #define PGID_BROADCAST 510
226 #define PGID_UNICAST 511
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",
240 #define REGS_NAMES_COUNT ARRAY_SIZE(regs_names) + 1
256 #define JR2_MIIM_BUS_COUNT 3
258 struct jr2_phy_port_t {
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];
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,
279 static struct mscc_miim_dev miim[JR2_MIIM_BUS_COUNT];
280 static int miim_count = -1;
282 static void jr2_cpu_capture_setup(struct jr2_private *priv)
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));
289 /* Set Manual injection via DEVCPU_QS registers for CPU queue 0 */
290 writel(0x5, priv->regs[QS] + QS_INJ_GRP_CFG(0));
292 /* Set Manual extraction via DEVCPU_QS registers for CPU queue 0 */
293 writel(0x7, priv->regs[QS] + QS_XTR_GRP_CFG(0));
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);
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);
304 static void jr2_port_init(struct jr2_private *priv, int port)
306 void __iomem *regs = priv->regs[port];
309 writel(DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA,
310 regs + DEV_PCS1G_CFG_PCS1G_CFG);
312 /* Disable Signal Detect */
313 writel(0, regs + DEV_PCS1G_CFG_PCS1G_SD);
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);
320 /* Clear sgmii_mode_ena */
321 writel(0, regs + DEV_PCS1G_CFG_PCS1G_MODE);
324 * Clear sw_resolve_ena(bit 0) and set adv_ability to
325 * something meaningful just in case
327 writel(DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(0x20),
328 regs + DEV_PCS1G_CFG_PCS1G_ANEG);
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);
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);
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) |
344 priv->regs[ANA_CL] + ANA_CL_PORT_VLAN_CFG(port));
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);
351 static void serdes6g_write(void __iomem *base, u32 addr)
355 writel(HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT |
356 HSIO_MCB_SERDES6G_CFG_ADDR(addr),
357 base + HSIO_MCB_SERDES6G_CFG);
360 data = readl(base + HSIO_MCB_SERDES6G_CFG);
361 } while (data & HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT);
364 static void serdes6g_setup(void __iomem *base, uint32_t addr,
365 phy_interface_t interface)
373 u32 ob_ena1v_mode = 0;
375 u32 pll_fsm_ctrl_data = 0;
378 case PHY_INTERFACE_MODE_SGMII:
387 pll_fsm_ctrl_data = 60;
389 case PHY_INTERFACE_MODE_QSGMII:
394 pll_fsm_ctrl_data = 120;
397 pr_err("Interface not supported\n");
401 if (interface == PHY_INTERFACE_MODE_QSGMII)
402 writel(0xfff, base + HSIO_HW_CFGSTAT_HW_CFG);
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);
436 serdes6g_write(base, addr);
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);
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);
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);
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);
490 serdes6g_write(base, addr);
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);
498 serdes6g_write(base, addr);
500 /* wait 20ms for pll bringup */
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);
523 serdes6g_write(base, addr);
525 /* wait 60 for calibration */
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);
555 serdes6g_write(base, addr);
558 static void serdes1g_write(void __iomem *base, u32 addr)
562 writel(HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT |
563 HSIO_MCB_SERDES1G_CFG_ADDR(addr),
564 base + HSIO_MCB_SERDES1G_CFG);
567 data = readl(base + HSIO_MCB_SERDES1G_CFG);
568 } while (data & HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT);
571 static void serdes1g_setup(void __iomem *base, uint32_t addr,
572 phy_interface_t interface)
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);
607 serdes1g_write(base, addr);
609 setbits_le32(base + HSIO_ANA_SERDES1G_COMMON_CFG,
610 HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST);
612 serdes1g_write(base, addr);
614 clrbits_le32(base + HSIO_DIG_SERDES1G_MISC_CFG,
615 HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST);
617 serdes1g_write(base, addr);
620 static int ram_init(u32 val, void __iomem *addr)
624 if (wait_for_bit_le32(addr, BIT(1), false, 2000, false)) {
625 printf("Timeout in memory reset, reg = 0x%08x\n", val);
632 static int jr2_switch_init(struct jr2_private *priv)
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);
641 writel(0x1, priv->regs[ANA_AC] + ANA_AC_STAT_GLOBAL_CFG_PORT_RESET);
642 writel(0x1, priv->regs[ASM] + ASM_CFG_STAT_CFG);
644 /* Enable switch-core and queue system */
645 writel(0x1, priv->regs[QSYS] + QSYS_SYSTEM_RESET_CFG);
650 static void jr2_switch_config(struct jr2_private *priv)
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));
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);
662 static int jr2_initialize(struct jr2_private *priv)
666 /* Initialize switch memories, enable core */
667 ret = jr2_switch_init(priv);
671 jr2_switch_config(priv);
673 for (i = 0; i < MAX_PORT; i++)
674 jr2_port_init(priv, i);
676 jr2_cpu_capture_setup(priv);
681 static inline int jr2_vlant_wait_for_completion(struct jr2_private *priv)
683 if (wait_for_bit_le32(priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL,
684 LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
691 static int jr2_mac_table_add(struct jr2_private *priv,
692 const unsigned char mac[ETH_ALEN], int pgid)
694 u32 macl = 0, mach = 0;
697 * Set the MAC address to handle and the vlan associated in a format
698 * understood by the hardware.
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;
708 writel(mach, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG0);
709 writel(macl, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG1);
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);
719 writel(LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
720 priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL);
722 return jr2_vlant_wait_for_completion(priv);
725 static int jr2_write_hwaddr(struct udevice *dev)
727 struct jr2_private *priv = dev_get_priv(dev);
728 struct eth_pdata *pdata = dev_get_platdata(dev);
730 return jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
733 static void serdes_setup(struct jr2_private *priv)
738 for (i = 0; i < MAX_PORT; ++i) {
739 if (!priv->ports[i].bus || priv->ports[i].serdes_index == 0xff)
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);
747 mask >>= SERDES6G(0);
748 serdes6g_setup(priv->regs[HSIO], mask,
749 priv->ports[i].phy_mode);
754 static int jr2_start(struct udevice *dev)
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,
762 ret = jr2_initialize(priv);
766 /* Set MAC address tables entries for CPU redirection */
767 ret = jr2_mac_table_add(priv, mac, PGID_BROADCAST);
771 ret = jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
780 static void jr2_stop(struct udevice *dev)
784 static int jr2_send(struct udevice *dev, void *packet, int length)
786 struct jr2_private *priv = dev_get_priv(dev);
790 memset(ifh, '\0', IFH_LEN);
792 /* Set DST PORT_MASK */
794 ifh[1] = htonl(0x1FFFFF);
796 /* Set DST_MODE to INJECT and UPDATE_FCS */
797 ifh[5] = htonl(0x4c0);
799 return mscc_send(priv->regs[QS], jr2_regs_qs,
800 ifh, IFH_LEN, buf, length);
803 static int jr2_recv(struct udevice *dev, int flags, uchar **packetp)
805 struct jr2_private *priv = dev_get_priv(dev);
806 u32 *rxbuf = (u32 *)net_rx_packets[0];
809 byte_cnt = mscc_recv(priv->regs[QS], jr2_regs_qs, rxbuf, IFH_LEN,
812 *packetp = net_rx_packets[0];
817 static struct mii_dev *get_mdiobus(phys_addr_t base, unsigned long size)
821 for (i = 0; i < JR2_MIIM_BUS_COUNT; ++i)
822 if (miim[i].miim_base == base && miim[i].miim_size == size)
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)
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;
838 static int jr2_probe(struct udevice *dev)
840 struct jr2_private *priv = dev_get_priv(dev);
845 phys_addr_t addr_base;
846 unsigned long addr_size;
847 ofnode eth_node, node, mdio_node;
850 struct ofnode_phandle_args phandle;
851 struct phy_device *phy;
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]) {
861 ("Error can't get regs base addresses for %s\n",
867 /* Initialize miim buses */
868 memset(&miim, 0x0, sizeof(struct mscc_miim_dev) * JR2_MIIM_BUS_COUNT);
870 /* iterate all the ports and find out on which bus they are */
872 eth_node = dev_read_first_subnode(dev);
873 for (node = ofnode_first_subnode(eth_node);
875 node = ofnode_next_subnode(node)) {
876 if (ofnode_read_resource(node, 0, &res))
880 ret = ofnode_parse_phandle_with_args(node, "phy-handle", NULL,
885 /* Get phy address on mdio bus */
886 if (ofnode_read_resource(phandle.node, 0, &res))
888 phy_addr = res.start;
891 mdio_node = ofnode_get_parent(phandle.node);
893 if (ofnode_read_resource(mdio_node, 0, &res))
895 faddr = cpu_to_fdt32(res.start);
897 addr_base = ofnode_translate_address(mdio_node, &faddr);
898 addr_size = res.end - res.start;
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,
906 /* Connect mdio bus with the port */
907 bus = get_mdiobus(addr_base, addr_size);
909 /* Get serdes info */
910 ret = ofnode_parse_phandle_with_args(node, "phys", NULL,
915 add_port_entry(priv, i, phy_addr, bus, phandle.args[1],
919 for (i = 0; i < MAX_PORT; i++) {
920 if (!priv->ports[i].bus)
923 phy = phy_connect(priv->ports[i].bus,
924 priv->ports[i].phy_addr, dev,
925 PHY_INTERFACE_MODE_NONE);
927 board_phy_config(phy);
933 static int jr2_remove(struct udevice *dev)
935 struct jr2_private *priv = dev_get_priv(dev);
938 for (i = 0; i < JR2_MIIM_BUS_COUNT; i++) {
939 mdio_unregister(priv->bus[i]);
940 mdio_free(priv->bus[i]);
946 static const struct eth_ops jr2_ops = {
951 .write_hwaddr = jr2_write_hwaddr,
954 static const struct udevice_id mscc_jr2_ids[] = {
955 {.compatible = "mscc,vsc7454-switch" },
959 U_BOOT_DRIVER(jr2) = {
960 .name = "jr2-switch",
962 .of_match = mscc_jr2_ids,
964 .remove = jr2_remove,
966 .priv_auto_alloc_size = sizeof(struct jr2_private),
967 .platdata_auto_alloc_size = sizeof(struct eth_pdata),