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/bitops.h>
14 #include <linux/delay.h>
16 #include <linux/ioport.h>
21 #include <dt-bindings/mscc/jr2_data.h>
22 #include "mscc_xfer.h"
23 #include "mscc_miim.h"
25 #define ANA_AC_RAM_CTRL_RAM_INIT 0x94358
26 #define ANA_AC_STAT_GLOBAL_CFG_PORT_RESET 0x94370
28 #define ANA_CL_PORT_VLAN_CFG(x) (0x24018 + 0xc8 * (x))
29 #define ANA_CL_PORT_VLAN_CFG_AWARE_ENA BIT(19)
30 #define ANA_CL_PORT_VLAN_CFG_POP_CNT(x) ((x) << 17)
32 #define ANA_L2_COMMON_FWD_CFG 0x8a2a8
33 #define ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA BIT(6)
35 #define ASM_CFG_STAT_CFG 0x3508
36 #define ASM_CFG_PORT(x) (0x36c4 + 0x4 * (x))
37 #define ASM_CFG_PORT_NO_PREAMBLE_ENA BIT(8)
38 #define ASM_CFG_PORT_INJ_FORMAT_CFG(x) ((x) << 1)
39 #define ASM_RAM_CTRL_RAM_INIT 0x39b8
41 #define DEV_DEV_CFG_DEV_RST_CTRL 0x0
42 #define DEV_DEV_CFG_DEV_RST_CTRL_SPEED_SEL(x) ((x) << 20)
43 #define DEV_MAC_CFG_MAC_ENA 0x1c
44 #define DEV_MAC_CFG_MAC_ENA_RX_ENA BIT(4)
45 #define DEV_MAC_CFG_MAC_ENA_TX_ENA BIT(0)
46 #define DEV_MAC_CFG_MAC_IFG 0x34
47 #define DEV_MAC_CFG_MAC_IFG_TX_IFG(x) ((x) << 8)
48 #define DEV_MAC_CFG_MAC_IFG_RX_IFG2(x) ((x) << 4)
49 #define DEV_MAC_CFG_MAC_IFG_RX_IFG1(x) (x)
50 #define DEV_PCS1G_CFG_PCS1G_CFG 0x40
51 #define DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA BIT(0)
52 #define DEV_PCS1G_CFG_PCS1G_MODE 0x44
53 #define DEV_PCS1G_CFG_PCS1G_SD 0x48
54 #define DEV_PCS1G_CFG_PCS1G_ANEG 0x4c
55 #define DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(x) ((x) << 16)
57 #define DSM_RAM_CTRL_RAM_INIT 0x8
59 #define HSIO_ANA_SERDES1G_DES_CFG 0xac
60 #define HSIO_ANA_SERDES1G_DES_CFG_BW_HYST(x) ((x) << 1)
61 #define HSIO_ANA_SERDES1G_DES_CFG_BW_ANA(x) ((x) << 5)
62 #define HSIO_ANA_SERDES1G_DES_CFG_MBTR_CTRL(x) ((x) << 8)
63 #define HSIO_ANA_SERDES1G_DES_CFG_PHS_CTRL(x) ((x) << 13)
64 #define HSIO_ANA_SERDES1G_IB_CFG 0xb0
65 #define HSIO_ANA_SERDES1G_IB_CFG_RESISTOR_CTRL(x) (x)
66 #define HSIO_ANA_SERDES1G_IB_CFG_EQ_GAIN(x) ((x) << 6)
67 #define HSIO_ANA_SERDES1G_IB_CFG_ENA_OFFSET_COMP BIT(9)
68 #define HSIO_ANA_SERDES1G_IB_CFG_ENA_DETLEV BIT(11)
69 #define HSIO_ANA_SERDES1G_IB_CFG_ENA_CMV_TERM BIT(13)
70 #define HSIO_ANA_SERDES1G_IB_CFG_DET_LEV(x) ((x) << 19)
71 #define HSIO_ANA_SERDES1G_IB_CFG_ACJTAG_HYST(x) ((x) << 24)
72 #define HSIO_ANA_SERDES1G_OB_CFG 0xb4
73 #define HSIO_ANA_SERDES1G_OB_CFG_RESISTOR_CTRL(x) (x)
74 #define HSIO_ANA_SERDES1G_OB_CFG_VCM_CTRL(x) ((x) << 4)
75 #define HSIO_ANA_SERDES1G_OB_CFG_CMM_BIAS_CTRL(x) ((x) << 10)
76 #define HSIO_ANA_SERDES1G_OB_CFG_AMP_CTRL(x) ((x) << 13)
77 #define HSIO_ANA_SERDES1G_OB_CFG_SLP(x) ((x) << 17)
78 #define HSIO_ANA_SERDES1G_SER_CFG 0xb8
79 #define HSIO_ANA_SERDES1G_COMMON_CFG 0xbc
80 #define HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE BIT(0)
81 #define HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE BIT(18)
82 #define HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST BIT(31)
83 #define HSIO_ANA_SERDES1G_PLL_CFG 0xc0
84 #define HSIO_ANA_SERDES1G_PLL_CFG_FSM_ENA BIT(7)
85 #define HSIO_ANA_SERDES1G_PLL_CFG_FSM_CTRL_DATA(x) ((x) << 8)
86 #define HSIO_ANA_SERDES1G_PLL_CFG_ENA_RC_DIV2 BIT(21)
87 #define HSIO_DIG_SERDES1G_DFT_CFG0 0xc8
88 #define HSIO_DIG_SERDES1G_TP_CFG 0xd4
89 #define HSIO_DIG_SERDES1G_MISC_CFG 0xdc
90 #define HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST BIT(0)
91 #define HSIO_MCB_SERDES1G_CFG 0xe8
92 #define HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT BIT(31)
93 #define HSIO_MCB_SERDES1G_CFG_ADDR(x) (x)
95 #define HSIO_ANA_SERDES6G_DES_CFG 0x11c
96 #define HSIO_ANA_SERDES6G_DES_CFG_SWAP_ANA BIT(0)
97 #define HSIO_ANA_SERDES6G_DES_CFG_BW_ANA(x) ((x) << 1)
98 #define HSIO_ANA_SERDES6G_DES_CFG_SWAP_HYST BIT(4)
99 #define HSIO_ANA_SERDES6G_DES_CFG_BW_HYST(x) ((x) << 5)
100 #define HSIO_ANA_SERDES6G_DES_CFG_CPMD_SEL(x) ((x) << 8)
101 #define HSIO_ANA_SERDES6G_DES_CFG_MBTR_CTRL(x) ((x) << 10)
102 #define HSIO_ANA_SERDES6G_DES_CFG_PHS_CTRL(x) ((x) << 13)
103 #define HSIO_ANA_SERDES6G_IB_CFG 0x120
104 #define HSIO_ANA_SERDES6G_IB_CFG_REG_ENA BIT(0)
105 #define HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA BIT(1)
106 #define HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA BIT(2)
107 #define HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(x) ((x) << 3)
108 #define HSIO_ANA_SERDES6G_IB_CFG_CONCUR BIT(4)
109 #define HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA BIT(5)
110 #define HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(x) ((x) << 7)
111 #define HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(x) ((x) << 9)
112 #define HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(x) ((x) << 11)
113 #define HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(x) ((x) << 13)
114 #define HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(x) ((x) << 15)
115 #define HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(x) ((x) << 18)
116 #define HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(x) ((x) << 20)
117 #define HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(x) ((x) << 24)
118 #define HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL BIT(28)
119 #define HSIO_ANA_SERDES6G_IB_CFG_SOFSI(x) ((x) << 29)
120 #define HSIO_ANA_SERDES6G_IB_CFG1 0x124
121 #define HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET BIT(4)
122 #define HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP BIT(5)
123 #define HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID BIT(6)
124 #define HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP BIT(7)
125 #define HSIO_ANA_SERDES6G_IB_CFG1_SCALY(x) ((x) << 8)
126 #define HSIO_ANA_SERDES6G_IB_CFG1_TSDET(x) ((x) << 12)
127 #define HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(x) ((x) << 17)
128 #define HSIO_ANA_SERDES6G_IB_CFG2 0x128
129 #define HSIO_ANA_SERDES6G_IB_CFG2_UREG(x) (x)
130 #define HSIO_ANA_SERDES6G_IB_CFG2_UMAX(x) ((x) << 3)
131 #define HSIO_ANA_SERDES6G_IB_CFG2_TCALV(x) ((x) << 5)
132 #define HSIO_ANA_SERDES6G_IB_CFG2_OCALS(x) ((x) << 10)
133 #define HSIO_ANA_SERDES6G_IB_CFG2_OINFS(x) ((x) << 16)
134 #define HSIO_ANA_SERDES6G_IB_CFG2_OINFI(x) ((x) << 22)
135 #define HSIO_ANA_SERDES6G_IB_CFG2_TINFV(x) ((x) << 27)
136 #define HSIO_ANA_SERDES6G_IB_CFG3 0x12c
137 #define HSIO_ANA_SERDES6G_IB_CFG3_INI_OFFSET(x) (x)
138 #define HSIO_ANA_SERDES6G_IB_CFG3_INI_LP(x) ((x) << 6)
139 #define HSIO_ANA_SERDES6G_IB_CFG3_INI_MID(x) ((x) << 12)
140 #define HSIO_ANA_SERDES6G_IB_CFG3_INI_HP(x) ((x) << 18)
141 #define HSIO_ANA_SERDES6G_IB_CFG4 0x130
142 #define HSIO_ANA_SERDES6G_IB_CFG4_MAX_OFFSET(x) (x)
143 #define HSIO_ANA_SERDES6G_IB_CFG4_MAX_LP(x) ((x) << 6)
144 #define HSIO_ANA_SERDES6G_IB_CFG4_MAX_MID(x) ((x) << 12)
145 #define HSIO_ANA_SERDES6G_IB_CFG4_MAX_HP(x) ((x) << 18)
146 #define HSIO_ANA_SERDES6G_IB_CFG5 0x134
147 #define HSIO_ANA_SERDES6G_IB_CFG4_MIN_OFFSET(x) (x)
148 #define HSIO_ANA_SERDES6G_IB_CFG4_MIN_LP(x) ((x) << 6)
149 #define HSIO_ANA_SERDES6G_IB_CFG4_MIN_MID(x) ((x) << 12)
150 #define HSIO_ANA_SERDES6G_IB_CFG4_MIN_HP(x) ((x) << 18)
151 #define HSIO_ANA_SERDES6G_OB_CFG 0x138
152 #define HSIO_ANA_SERDES6G_OB_CFG_RESISTOR_CTRL(x) (x)
153 #define HSIO_ANA_SERDES6G_OB_CFG_SR(x) ((x) << 4)
154 #define HSIO_ANA_SERDES6G_OB_CFG_SR_H BIT(8)
155 #define HSIO_ANA_SERDES6G_OB_CFG_SEL_RCTRL BIT(9)
156 #define HSIO_ANA_SERDES6G_OB_CFG_R_COR BIT(10)
157 #define HSIO_ANA_SERDES6G_OB_CFG_POST1(x) ((x) << 11)
158 #define HSIO_ANA_SERDES6G_OB_CFG_R_ADJ_PDR BIT(16)
159 #define HSIO_ANA_SERDES6G_OB_CFG_R_ADJ_MUX BIT(17)
160 #define HSIO_ANA_SERDES6G_OB_CFG_PREC(x) ((x) << 18)
161 #define HSIO_ANA_SERDES6G_OB_CFG_POST0(x) ((x) << 23)
162 #define HSIO_ANA_SERDES6G_OB_CFG_POL BIT(29)
163 #define HSIO_ANA_SERDES6G_OB_CFG_ENA1V_MODE(x) ((x) << 30)
164 #define HSIO_ANA_SERDES6G_OB_CFG_IDLE BIT(31)
165 #define HSIO_ANA_SERDES6G_OB_CFG1 0x13c
166 #define HSIO_ANA_SERDES6G_OB_CFG1_LEV(x) (x)
167 #define HSIO_ANA_SERDES6G_OB_CFG1_ENA_CAS(x) ((x) << 6)
168 #define HSIO_ANA_SERDES6G_SER_CFG 0x140
169 #define HSIO_ANA_SERDES6G_COMMON_CFG 0x144
170 #define HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(x) (x)
171 #define HSIO_ANA_SERDES6G_COMMON_CFG_QRATE(x) (x << 2)
172 #define HSIO_ANA_SERDES6G_COMMON_CFG_ENA_LANE BIT(14)
173 #define HSIO_ANA_SERDES6G_COMMON_CFG_SYS_RST BIT(16)
174 #define HSIO_ANA_SERDES6G_PLL_CFG 0x148
175 #define HSIO_ANA_SERDES6G_PLL_CFG_ROT_FRQ BIT(0)
176 #define HSIO_ANA_SERDES6G_PLL_CFG_ROT_DIR BIT(1)
177 #define HSIO_ANA_SERDES6G_PLL_CFG_RB_DATA_SEL BIT(2)
178 #define HSIO_ANA_SERDES6G_PLL_CFG_FSM_OOR_RECAL_ENA BIT(3)
179 #define HSIO_ANA_SERDES6G_PLL_CFG_FSM_FORCE_SET_ENA BIT(4)
180 #define HSIO_ANA_SERDES6G_PLL_CFG_FSM_ENA BIT(5)
181 #define HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(x) ((x) << 6)
182 #define HSIO_ANA_SERDES6G_PLL_CFG_ENA_ROT BIT(14)
183 #define HSIO_ANA_SERDES6G_PLL_CFG_DIV4 BIT(15)
184 #define HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(x) ((x) << 16)
185 #define HSIO_DIG_SERDES6G_MISC_CFG 0x108
186 #define HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST BIT(0)
187 #define HSIO_MCB_SERDES6G_CFG 0x168
188 #define HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT BIT(31)
189 #define HSIO_MCB_SERDES6G_CFG_ADDR(x) (x)
190 #define HSIO_HW_CFGSTAT_HW_CFG 0x16c
192 #define LRN_COMMON_ACCESS_CTRL 0x0
193 #define LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT BIT(0)
194 #define LRN_COMMON_MAC_ACCESS_CFG0 0x4
195 #define LRN_COMMON_MAC_ACCESS_CFG1 0x8
196 #define LRN_COMMON_MAC_ACCESS_CFG2 0xc
197 #define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_ADDR(x) (x)
198 #define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_TYPE(x) ((x) << 12)
199 #define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_VLD BIT(15)
200 #define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_LOCKED BIT(16)
201 #define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_COPY BIT(23)
202 #define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_QU(x) ((x) << 24)
204 #define QFWD_SYSTEM_SWITCH_PORT_MODE(x) (0x4 * (x))
205 #define QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA BIT(17)
207 #define QS_XTR_GRP_CFG(x) (0x0 + 4 * (x))
208 #define QS_INJ_GRP_CFG(x) (0x24 + (x) * 4)
210 #define QSYS_SYSTEM_RESET_CFG 0xf0
211 #define QSYS_CALCFG_CAL_AUTO(x) (0x3d4 + 4 * (x))
212 #define QSYS_CALCFG_CAL_CTRL 0x3e8
213 #define QSYS_CALCFG_CAL_CTRL_CAL_MODE(x) ((x) << 11)
214 #define QSYS_RAM_CTRL_RAM_INIT 0x3ec
216 #define REW_RAM_CTRL_RAM_INIT 0x53528
218 #define VOP_RAM_CTRL_RAM_INIT 0x43638
220 #define XTR_VALID_BYTES(x) (4 - ((x) & 3))
224 #define JR2_BUF_CELL_SZ 60
226 #define PGID_BROADCAST 510
227 #define PGID_UNICAST 511
229 static const char * const regs_names[] = {
230 "port0", "port1", "port2", "port3", "port4", "port5", "port6", "port7",
231 "port8", "port9", "port10", "port11", "port12", "port13", "port14",
232 "port15", "port16", "port17", "port18", "port19", "port20", "port21",
233 "port22", "port23", "port24", "port25", "port26", "port27", "port28",
234 "port29", "port30", "port31", "port32", "port33", "port34", "port35",
235 "port36", "port37", "port38", "port39", "port40", "port41", "port42",
236 "port43", "port44", "port45", "port46", "port47",
237 "ana_ac", "ana_cl", "ana_l2", "asm", "hsio", "lrn",
238 "qfwd", "qs", "qsys", "rew",
241 #define REGS_NAMES_COUNT ARRAY_SIZE(regs_names) + 1
257 #define JR2_MIIM_BUS_COUNT 3
259 struct jr2_phy_port_t {
267 void __iomem *regs[REGS_NAMES_COUNT];
268 struct mii_dev *bus[JR2_MIIM_BUS_COUNT];
269 struct jr2_phy_port_t ports[MAX_PORT];
272 static const unsigned long jr2_regs_qs[] = {
273 [MSCC_QS_XTR_RD] = 0x8,
274 [MSCC_QS_XTR_FLUSH] = 0x18,
275 [MSCC_QS_XTR_DATA_PRESENT] = 0x1c,
276 [MSCC_QS_INJ_WR] = 0x2c,
277 [MSCC_QS_INJ_CTRL] = 0x34,
280 static struct mscc_miim_dev miim[JR2_MIIM_BUS_COUNT];
281 static int miim_count = -1;
283 static void jr2_cpu_capture_setup(struct jr2_private *priv)
285 /* ASM: No preamble and IFH prefix on CPU injected frames */
286 writel(ASM_CFG_PORT_NO_PREAMBLE_ENA |
287 ASM_CFG_PORT_INJ_FORMAT_CFG(1),
288 priv->regs[ASM] + ASM_CFG_PORT(CPU_PORT));
290 /* Set Manual injection via DEVCPU_QS registers for CPU queue 0 */
291 writel(0x5, priv->regs[QS] + QS_INJ_GRP_CFG(0));
293 /* Set Manual extraction via DEVCPU_QS registers for CPU queue 0 */
294 writel(0x7, priv->regs[QS] + QS_XTR_GRP_CFG(0));
296 /* Enable CPU port for any frame transfer */
297 setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(CPU_PORT),
298 QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA);
300 /* Send a copy to CPU when found as forwarding entry */
301 setbits_le32(priv->regs[ANA_L2] + ANA_L2_COMMON_FWD_CFG,
302 ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA);
305 static void jr2_port_init(struct jr2_private *priv, int port)
307 void __iomem *regs = priv->regs[port];
310 writel(DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA,
311 regs + DEV_PCS1G_CFG_PCS1G_CFG);
313 /* Disable Signal Detect */
314 writel(0, regs + DEV_PCS1G_CFG_PCS1G_SD);
316 /* Enable MAC RX and TX */
317 writel(DEV_MAC_CFG_MAC_ENA_RX_ENA |
318 DEV_MAC_CFG_MAC_ENA_TX_ENA,
319 regs + DEV_MAC_CFG_MAC_ENA);
321 /* Clear sgmii_mode_ena */
322 writel(0, regs + DEV_PCS1G_CFG_PCS1G_MODE);
325 * Clear sw_resolve_ena(bit 0) and set adv_ability to
326 * something meaningful just in case
328 writel(DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(0x20),
329 regs + DEV_PCS1G_CFG_PCS1G_ANEG);
331 /* Set MAC IFG Gaps */
332 writel(DEV_MAC_CFG_MAC_IFG_TX_IFG(4) |
333 DEV_MAC_CFG_MAC_IFG_RX_IFG1(5) |
334 DEV_MAC_CFG_MAC_IFG_RX_IFG2(1),
335 regs + DEV_MAC_CFG_MAC_IFG);
337 /* Set link speed and release all resets */
338 writel(DEV_DEV_CFG_DEV_RST_CTRL_SPEED_SEL(2),
339 regs + DEV_DEV_CFG_DEV_RST_CTRL);
341 /* Make VLAN aware for CPU traffic */
342 writel(ANA_CL_PORT_VLAN_CFG_AWARE_ENA |
343 ANA_CL_PORT_VLAN_CFG_POP_CNT(1) |
345 priv->regs[ANA_CL] + ANA_CL_PORT_VLAN_CFG(port));
347 /* Enable CPU port for any frame transfer */
348 setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(port),
349 QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA);
352 static void serdes6g_write(void __iomem *base, u32 addr)
356 writel(HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT |
357 HSIO_MCB_SERDES6G_CFG_ADDR(addr),
358 base + HSIO_MCB_SERDES6G_CFG);
361 data = readl(base + HSIO_MCB_SERDES6G_CFG);
362 } while (data & HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT);
365 static void serdes6g_setup(void __iomem *base, uint32_t addr,
366 phy_interface_t interface)
374 u32 ob_ena1v_mode = 0;
376 u32 pll_fsm_ctrl_data = 0;
379 case PHY_INTERFACE_MODE_SGMII:
388 pll_fsm_ctrl_data = 60;
390 case PHY_INTERFACE_MODE_QSGMII:
395 pll_fsm_ctrl_data = 120;
398 pr_err("Interface not supported\n");
402 if (interface == PHY_INTERFACE_MODE_QSGMII)
403 writel(0xfff, base + HSIO_HW_CFGSTAT_HW_CFG);
405 writel(HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(3),
406 base + HSIO_ANA_SERDES6G_COMMON_CFG);
407 writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(120) |
408 HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
409 base + HSIO_ANA_SERDES6G_PLL_CFG);
410 writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
411 HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
412 HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
413 HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
414 HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
415 HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
416 HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
417 HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
418 HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
419 HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(7) |
420 HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
421 HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
422 HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
423 HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
424 HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
425 base + HSIO_ANA_SERDES6G_IB_CFG);
426 writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
427 HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
428 HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
429 HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
430 HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
431 HSIO_ANA_SERDES6G_IB_CFG1_TSDET(3) |
432 HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
433 base + HSIO_ANA_SERDES6G_IB_CFG1);
434 writel(HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST,
435 base + HSIO_DIG_SERDES6G_MISC_CFG);
437 serdes6g_write(base, addr);
439 writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
440 HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
441 HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
442 HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
443 HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
444 HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
445 HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
446 HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
447 HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
448 HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(0) |
449 HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
450 HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
451 HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
452 HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
453 HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
454 base + HSIO_ANA_SERDES6G_IB_CFG);
455 writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
456 HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
457 HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
458 HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
459 HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
460 HSIO_ANA_SERDES6G_IB_CFG1_TSDET(16) |
461 HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
462 base + HSIO_ANA_SERDES6G_IB_CFG1);
464 writel(0x0, base + HSIO_ANA_SERDES6G_SER_CFG);
465 writel(HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(ib_if_mode) |
466 HSIO_ANA_SERDES6G_COMMON_CFG_QRATE(ib_qrate) |
467 HSIO_ANA_SERDES6G_COMMON_CFG_ENA_LANE |
468 HSIO_ANA_SERDES6G_COMMON_CFG_SYS_RST,
469 base + HSIO_ANA_SERDES6G_COMMON_CFG);
470 writel(HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST,
471 base + HSIO_DIG_SERDES6G_MISC_CFG);
473 writel(HSIO_ANA_SERDES6G_OB_CFG_RESISTOR_CTRL(1) |
474 HSIO_ANA_SERDES6G_OB_CFG_SR(7) |
475 HSIO_ANA_SERDES6G_OB_CFG_SR_H |
476 HSIO_ANA_SERDES6G_OB_CFG_ENA1V_MODE(ob_ena1v_mode) |
477 HSIO_ANA_SERDES6G_OB_CFG_POL, base + HSIO_ANA_SERDES6G_OB_CFG);
478 writel(HSIO_ANA_SERDES6G_OB_CFG1_LEV(ob_lev) |
479 HSIO_ANA_SERDES6G_OB_CFG1_ENA_CAS(ob_ena_cas),
480 base + HSIO_ANA_SERDES6G_OB_CFG1);
482 writel(HSIO_ANA_SERDES6G_DES_CFG_BW_ANA(des_bw_ana) |
483 HSIO_ANA_SERDES6G_DES_CFG_BW_HYST(5) |
484 HSIO_ANA_SERDES6G_DES_CFG_MBTR_CTRL(2) |
485 HSIO_ANA_SERDES6G_DES_CFG_PHS_CTRL(6),
486 base + HSIO_ANA_SERDES6G_DES_CFG);
487 writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(pll_fsm_ctrl_data) |
488 HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
489 base + HSIO_ANA_SERDES6G_PLL_CFG);
491 serdes6g_write(base, addr);
493 /* set pll_fsm_ena = 1 */
494 writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_ENA |
495 HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(pll_fsm_ctrl_data) |
496 HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
497 base + HSIO_ANA_SERDES6G_PLL_CFG);
499 serdes6g_write(base, addr);
501 /* wait 20ms for pll bringup */
504 /* start IB calibration by setting ib_cal_ena and clearing lane_rst */
505 writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
506 HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
507 HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
508 HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(ib_cal_ena) |
509 HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
510 HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
511 HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
512 HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
513 HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
514 HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
515 HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(0) |
516 HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
517 HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
518 HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
519 HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
520 HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
521 base + HSIO_ANA_SERDES6G_IB_CFG);
522 writel(0x0, base + HSIO_DIG_SERDES6G_MISC_CFG);
524 serdes6g_write(base, addr);
526 /* wait 60 for calibration */
529 /* set ib_tsdet and ib_reg_pat_sel_offset back to correct values */
530 writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
531 HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
532 HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
533 HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(ib_cal_ena) |
534 HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
535 HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
536 HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
537 HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
538 HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
539 HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
540 HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(7) |
541 HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
542 HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
543 HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
544 HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
545 HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
546 base + HSIO_ANA_SERDES6G_IB_CFG);
547 writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
548 HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
549 HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
550 HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
551 HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
552 HSIO_ANA_SERDES6G_IB_CFG1_TSDET(ib1_tsdet) |
553 HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
554 base + HSIO_ANA_SERDES6G_IB_CFG1);
556 serdes6g_write(base, addr);
559 static void serdes1g_write(void __iomem *base, u32 addr)
563 writel(HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT |
564 HSIO_MCB_SERDES1G_CFG_ADDR(addr),
565 base + HSIO_MCB_SERDES1G_CFG);
568 data = readl(base + HSIO_MCB_SERDES1G_CFG);
569 } while (data & HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT);
572 static void serdes1g_setup(void __iomem *base, uint32_t addr,
573 phy_interface_t interface)
575 writel(0x0, base + HSIO_ANA_SERDES1G_SER_CFG);
576 writel(0x0, base + HSIO_DIG_SERDES1G_TP_CFG);
577 writel(0x0, base + HSIO_DIG_SERDES1G_DFT_CFG0);
578 writel(HSIO_ANA_SERDES1G_OB_CFG_RESISTOR_CTRL(1) |
579 HSIO_ANA_SERDES1G_OB_CFG_VCM_CTRL(4) |
580 HSIO_ANA_SERDES1G_OB_CFG_CMM_BIAS_CTRL(2) |
581 HSIO_ANA_SERDES1G_OB_CFG_AMP_CTRL(12) |
582 HSIO_ANA_SERDES1G_OB_CFG_SLP(3),
583 base + HSIO_ANA_SERDES1G_OB_CFG);
584 writel(HSIO_ANA_SERDES1G_IB_CFG_RESISTOR_CTRL(13) |
585 HSIO_ANA_SERDES1G_IB_CFG_EQ_GAIN(2) |
586 HSIO_ANA_SERDES1G_IB_CFG_ENA_OFFSET_COMP |
587 HSIO_ANA_SERDES1G_IB_CFG_ENA_DETLEV |
588 HSIO_ANA_SERDES1G_IB_CFG_ENA_CMV_TERM |
589 HSIO_ANA_SERDES1G_IB_CFG_DET_LEV(3) |
590 HSIO_ANA_SERDES1G_IB_CFG_ACJTAG_HYST(1),
591 base + HSIO_ANA_SERDES1G_IB_CFG);
592 writel(HSIO_ANA_SERDES1G_DES_CFG_BW_HYST(7) |
593 HSIO_ANA_SERDES1G_DES_CFG_BW_ANA(6) |
594 HSIO_ANA_SERDES1G_DES_CFG_MBTR_CTRL(2) |
595 HSIO_ANA_SERDES1G_DES_CFG_PHS_CTRL(6),
596 base + HSIO_ANA_SERDES1G_DES_CFG);
597 writel(HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST,
598 base + HSIO_DIG_SERDES1G_MISC_CFG);
599 writel(HSIO_ANA_SERDES1G_PLL_CFG_FSM_ENA |
600 HSIO_ANA_SERDES1G_PLL_CFG_FSM_CTRL_DATA(0xc8) |
601 HSIO_ANA_SERDES1G_PLL_CFG_ENA_RC_DIV2,
602 base + HSIO_ANA_SERDES1G_PLL_CFG);
603 writel(HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE |
604 HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE |
605 HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST,
606 base + HSIO_ANA_SERDES1G_COMMON_CFG);
608 serdes1g_write(base, addr);
610 setbits_le32(base + HSIO_ANA_SERDES1G_COMMON_CFG,
611 HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST);
613 serdes1g_write(base, addr);
615 clrbits_le32(base + HSIO_DIG_SERDES1G_MISC_CFG,
616 HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST);
618 serdes1g_write(base, addr);
621 static int ram_init(u32 val, void __iomem *addr)
625 if (wait_for_bit_le32(addr, BIT(1), false, 2000, false)) {
626 printf("Timeout in memory reset, reg = 0x%08x\n", val);
633 static int jr2_switch_init(struct jr2_private *priv)
635 /* Initialize memories */
636 ram_init(0x3, priv->regs[QSYS] + QSYS_RAM_CTRL_RAM_INIT);
637 ram_init(0x3, priv->regs[ASM] + ASM_RAM_CTRL_RAM_INIT);
638 ram_init(0x3, priv->regs[ANA_AC] + ANA_AC_RAM_CTRL_RAM_INIT);
639 ram_init(0x3, priv->regs[REW] + REW_RAM_CTRL_RAM_INIT);
642 writel(0x1, priv->regs[ANA_AC] + ANA_AC_STAT_GLOBAL_CFG_PORT_RESET);
643 writel(0x1, priv->regs[ASM] + ASM_CFG_STAT_CFG);
645 /* Enable switch-core and queue system */
646 writel(0x1, priv->regs[QSYS] + QSYS_SYSTEM_RESET_CFG);
651 static void jr2_switch_config(struct jr2_private *priv)
653 writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(0));
654 writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(1));
655 writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(2));
656 writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(3));
658 writel(readl(priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL) |
659 QSYS_CALCFG_CAL_CTRL_CAL_MODE(8),
660 priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL);
663 static int jr2_initialize(struct jr2_private *priv)
667 /* Initialize switch memories, enable core */
668 ret = jr2_switch_init(priv);
672 jr2_switch_config(priv);
674 for (i = 0; i < MAX_PORT; i++)
675 jr2_port_init(priv, i);
677 jr2_cpu_capture_setup(priv);
682 static inline int jr2_vlant_wait_for_completion(struct jr2_private *priv)
684 if (wait_for_bit_le32(priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL,
685 LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
692 static int jr2_mac_table_add(struct jr2_private *priv,
693 const unsigned char mac[ETH_ALEN], int pgid)
695 u32 macl = 0, mach = 0;
698 * Set the MAC address to handle and the vlan associated in a format
699 * understood by the hardware.
701 mach |= MAC_VID << 16;
702 mach |= ((u32)mac[0]) << 8;
703 mach |= ((u32)mac[1]) << 0;
704 macl |= ((u32)mac[2]) << 24;
705 macl |= ((u32)mac[3]) << 16;
706 macl |= ((u32)mac[4]) << 8;
707 macl |= ((u32)mac[5]) << 0;
709 writel(mach, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG0);
710 writel(macl, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG1);
712 writel(LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_ADDR(pgid) |
713 LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_TYPE(0x3) |
714 LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_COPY |
715 LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_QU(0) |
716 LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_VLD |
717 LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_LOCKED,
718 priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG2);
720 writel(LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
721 priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL);
723 return jr2_vlant_wait_for_completion(priv);
726 static int jr2_write_hwaddr(struct udevice *dev)
728 struct jr2_private *priv = dev_get_priv(dev);
729 struct eth_pdata *pdata = dev_get_platdata(dev);
731 return jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
734 static void serdes_setup(struct jr2_private *priv)
739 for (i = 0; i < MAX_PORT; ++i) {
740 if (!priv->ports[i].bus || priv->ports[i].serdes_index == 0xff)
743 mask = BIT(priv->ports[i].serdes_index);
744 if (priv->ports[i].serdes_index < SERDES1G_MAX) {
745 serdes1g_setup(priv->regs[HSIO], mask,
746 priv->ports[i].phy_mode);
748 mask >>= SERDES6G(0);
749 serdes6g_setup(priv->regs[HSIO], mask,
750 priv->ports[i].phy_mode);
755 static int jr2_start(struct udevice *dev)
757 struct jr2_private *priv = dev_get_priv(dev);
758 struct eth_pdata *pdata = dev_get_platdata(dev);
759 const unsigned char mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff,
763 ret = jr2_initialize(priv);
767 /* Set MAC address tables entries for CPU redirection */
768 ret = jr2_mac_table_add(priv, mac, PGID_BROADCAST);
772 ret = jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
781 static void jr2_stop(struct udevice *dev)
785 static int jr2_send(struct udevice *dev, void *packet, int length)
787 struct jr2_private *priv = dev_get_priv(dev);
791 memset(ifh, '\0', IFH_LEN);
793 /* Set DST PORT_MASK */
795 ifh[1] = htonl(0x1FFFFF);
797 /* Set DST_MODE to INJECT and UPDATE_FCS */
798 ifh[5] = htonl(0x4c0);
800 return mscc_send(priv->regs[QS], jr2_regs_qs,
801 ifh, IFH_LEN, buf, length);
804 static int jr2_recv(struct udevice *dev, int flags, uchar **packetp)
806 struct jr2_private *priv = dev_get_priv(dev);
807 u32 *rxbuf = (u32 *)net_rx_packets[0];
810 byte_cnt = mscc_recv(priv->regs[QS], jr2_regs_qs, rxbuf, IFH_LEN,
813 *packetp = net_rx_packets[0];
818 static struct mii_dev *get_mdiobus(phys_addr_t base, unsigned long size)
822 for (i = 0; i < JR2_MIIM_BUS_COUNT; ++i)
823 if (miim[i].miim_base == base && miim[i].miim_size == size)
829 static void add_port_entry(struct jr2_private *priv, size_t index,
830 size_t phy_addr, struct mii_dev *bus,
831 u8 serdes_index, u8 phy_mode)
833 priv->ports[index].phy_addr = phy_addr;
834 priv->ports[index].bus = bus;
835 priv->ports[index].serdes_index = serdes_index;
836 priv->ports[index].phy_mode = phy_mode;
839 static int jr2_probe(struct udevice *dev)
841 struct jr2_private *priv = dev_get_priv(dev);
846 phys_addr_t addr_base;
847 unsigned long addr_size;
848 ofnode eth_node, node, mdio_node;
851 struct ofnode_phandle_args phandle;
852 struct phy_device *phy;
857 /* Get registers and map them to the private structure */
858 for (i = 0; i < ARRAY_SIZE(regs_names); i++) {
859 priv->regs[i] = dev_remap_addr_name(dev, regs_names[i]);
860 if (!priv->regs[i]) {
862 ("Error can't get regs base addresses for %s\n",
868 /* Initialize miim buses */
869 memset(&miim, 0x0, sizeof(struct mscc_miim_dev) * JR2_MIIM_BUS_COUNT);
871 /* iterate all the ports and find out on which bus they are */
873 eth_node = dev_read_first_subnode(dev);
874 for (node = ofnode_first_subnode(eth_node);
876 node = ofnode_next_subnode(node)) {
877 if (ofnode_read_resource(node, 0, &res))
881 ret = ofnode_parse_phandle_with_args(node, "phy-handle", NULL,
886 /* Get phy address on mdio bus */
887 if (ofnode_read_resource(phandle.node, 0, &res))
889 phy_addr = res.start;
892 mdio_node = ofnode_get_parent(phandle.node);
894 if (ofnode_read_resource(mdio_node, 0, &res))
896 faddr = cpu_to_fdt32(res.start);
898 addr_base = ofnode_translate_address(mdio_node, &faddr);
899 addr_size = res.end - res.start;
901 /* If the bus is new then create a new bus */
902 if (!get_mdiobus(addr_base, addr_size))
903 priv->bus[miim_count] =
904 mscc_mdiobus_init(miim, &miim_count, addr_base,
907 /* Connect mdio bus with the port */
908 bus = get_mdiobus(addr_base, addr_size);
910 /* Get serdes info */
911 ret = ofnode_parse_phandle_with_args(node, "phys", NULL,
916 add_port_entry(priv, i, phy_addr, bus, phandle.args[1],
920 for (i = 0; i < MAX_PORT; i++) {
921 if (!priv->ports[i].bus)
924 phy = phy_connect(priv->ports[i].bus,
925 priv->ports[i].phy_addr, dev,
926 PHY_INTERFACE_MODE_NONE);
928 board_phy_config(phy);
934 static int jr2_remove(struct udevice *dev)
936 struct jr2_private *priv = dev_get_priv(dev);
939 for (i = 0; i < JR2_MIIM_BUS_COUNT; i++) {
940 mdio_unregister(priv->bus[i]);
941 mdio_free(priv->bus[i]);
947 static const struct eth_ops jr2_ops = {
952 .write_hwaddr = jr2_write_hwaddr,
955 static const struct udevice_id mscc_jr2_ids[] = {
956 {.compatible = "mscc,vsc7454-switch" },
960 U_BOOT_DRIVER(jr2) = {
961 .name = "jr2-switch",
963 .of_match = mscc_jr2_ids,
965 .remove = jr2_remove,
967 .priv_auto_alloc_size = sizeof(struct jr2_private),
968 .platdata_auto_alloc_size = sizeof(struct eth_pdata),