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