1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2 /*
3  * Copyright (c) 2018 Microsemi Corporation
4  */
5 
6 #include <common.h>
7 #include <config.h>
8 #include <dm.h>
9 #include <malloc.h>
10 #include <dm/of_access.h>
11 #include <dm/of_addr.h>
12 #include <fdt_support.h>
13 #include <linux/bitops.h>
14 #include <linux/delay.h>
15 #include <linux/io.h>
16 #include <linux/ioport.h>
17 #include <miiphy.h>
18 #include <net.h>
19 #include <wait_bit.h>
20 
21 #include <dt-bindings/mscc/jr2_data.h>
22 #include "mscc_xfer.h"
23 #include "mscc_miim.h"
24 
25 #define ANA_AC_RAM_CTRL_RAM_INIT		0x94358
26 #define ANA_AC_STAT_GLOBAL_CFG_PORT_RESET	0x94370
27 
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)
31 
32 #define ANA_L2_COMMON_FWD_CFG			0x8a2a8
33 #define		ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA	BIT(6)
34 
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
40 
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)
56 
57 #define DSM_RAM_CTRL_RAM_INIT		0x8
58 
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)
94 
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
191 
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)
203 
204 #define QFWD_SYSTEM_SWITCH_PORT_MODE(x)		(0x4 * (x))
205 #define		QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA		BIT(17)
206 
207 #define QS_XTR_GRP_CFG(x)		(0x0 + 4 * (x))
208 #define QS_INJ_GRP_CFG(x)		(0x24 + (x) * 4)
209 
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
215 
216 #define REW_RAM_CTRL_RAM_INIT			0x53528
217 
218 #define VOP_RAM_CTRL_RAM_INIT			0x43638
219 
220 #define XTR_VALID_BYTES(x)	(4 - ((x) & 3))
221 #define MAC_VID			0
222 #define CPU_PORT		53
223 #define IFH_LEN			7
224 #define JR2_BUF_CELL_SZ		60
225 #define ETH_ALEN		6
226 #define PGID_BROADCAST		510
227 #define PGID_UNICAST		511
228 
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",
239 };
240 
241 #define REGS_NAMES_COUNT ARRAY_SIZE(regs_names) + 1
242 #define MAX_PORT 48
243 
244 enum jr2_ctrl_regs {
245 	ANA_AC = MAX_PORT,
246 	ANA_CL,
247 	ANA_L2,
248 	ASM,
249 	HSIO,
250 	LRN,
251 	QFWD,
252 	QS,
253 	QSYS,
254 	REW,
255 };
256 
257 #define JR2_MIIM_BUS_COUNT 3
258 
259 struct jr2_phy_port_t {
260 	size_t phy_addr;
261 	struct mii_dev *bus;
262 	u8 serdes_index;
263 	u8 phy_mode;
264 };
265 
266 struct jr2_private {
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];
270 };
271 
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,
278 };
279 
280 static struct mscc_miim_dev miim[JR2_MIIM_BUS_COUNT];
281 static int miim_count = -1;
282 
jr2_cpu_capture_setup(struct jr2_private * priv)283 static void jr2_cpu_capture_setup(struct jr2_private *priv)
284 {
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));
289 
290 	/* Set Manual injection via DEVCPU_QS registers for CPU queue 0 */
291 	writel(0x5, priv->regs[QS] + QS_INJ_GRP_CFG(0));
292 
293 	/* Set Manual extraction via DEVCPU_QS registers for CPU queue 0 */
294 	writel(0x7, priv->regs[QS] + QS_XTR_GRP_CFG(0));
295 
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);
299 
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);
303 }
304 
jr2_port_init(struct jr2_private * priv,int port)305 static void jr2_port_init(struct jr2_private *priv, int port)
306 {
307 	void __iomem *regs = priv->regs[port];
308 
309 	/* Enable PCS */
310 	writel(DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA,
311 	       regs + DEV_PCS1G_CFG_PCS1G_CFG);
312 
313 	/* Disable Signal Detect */
314 	writel(0, regs + DEV_PCS1G_CFG_PCS1G_SD);
315 
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);
320 
321 	/* Clear sgmii_mode_ena */
322 	writel(0, regs + DEV_PCS1G_CFG_PCS1G_MODE);
323 
324 	/*
325 	 * Clear sw_resolve_ena(bit 0) and set adv_ability to
326 	 * something meaningful just in case
327 	 */
328 	writel(DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(0x20),
329 	       regs + DEV_PCS1G_CFG_PCS1G_ANEG);
330 
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);
336 
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);
340 
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) |
344 	       MAC_VID,
345 	       priv->regs[ANA_CL] + ANA_CL_PORT_VLAN_CFG(port));
346 
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);
350 }
351 
serdes6g_write(void __iomem * base,u32 addr)352 static void serdes6g_write(void __iomem *base, u32 addr)
353 {
354 	u32 data;
355 
356 	writel(HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT |
357 	       HSIO_MCB_SERDES6G_CFG_ADDR(addr),
358 	       base + HSIO_MCB_SERDES6G_CFG);
359 
360 	do {
361 		data = readl(base + HSIO_MCB_SERDES6G_CFG);
362 	} while (data & HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT);
363 }
364 
serdes6g_setup(void __iomem * base,uint32_t addr,phy_interface_t interface)365 static void serdes6g_setup(void __iomem *base, uint32_t addr,
366 			   phy_interface_t interface)
367 {
368 	u32 ib_if_mode = 0;
369 	u32 ib_qrate = 0;
370 	u32 ib_cal_ena = 0;
371 	u32 ib1_tsdet = 0;
372 	u32 ob_lev = 0;
373 	u32 ob_ena_cas = 0;
374 	u32 ob_ena1v_mode = 0;
375 	u32 des_bw_ana = 0;
376 	u32 pll_fsm_ctrl_data = 0;
377 
378 	switch (interface) {
379 	case PHY_INTERFACE_MODE_SGMII:
380 		ib_if_mode = 1;
381 		ib_qrate = 1;
382 		ib_cal_ena = 1;
383 		ib1_tsdet = 3;
384 		ob_lev = 48;
385 		ob_ena_cas = 2;
386 		ob_ena1v_mode = 1;
387 		des_bw_ana = 3;
388 		pll_fsm_ctrl_data = 60;
389 		break;
390 	case PHY_INTERFACE_MODE_QSGMII:
391 		ib_if_mode = 3;
392 		ib1_tsdet = 16;
393 		ob_lev = 24;
394 		des_bw_ana = 5;
395 		pll_fsm_ctrl_data = 120;
396 		break;
397 	default:
398 		pr_err("Interface not supported\n");
399 		return;
400 	}
401 
402 	if (interface == PHY_INTERFACE_MODE_QSGMII)
403 		writel(0xfff, base + HSIO_HW_CFGSTAT_HW_CFG);
404 
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);
436 
437 	serdes6g_write(base, addr);
438 
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);
463 
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);
472 
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);
481 
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);
490 
491 	serdes6g_write(base, addr);
492 
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);
498 
499 	serdes6g_write(base, addr);
500 
501 	/* wait 20ms for pll bringup */
502 	mdelay(20);
503 
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);
523 
524 	serdes6g_write(base, addr);
525 
526 	/* wait 60 for calibration */
527 	mdelay(60);
528 
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);
555 
556 	serdes6g_write(base, addr);
557 }
558 
serdes1g_write(void __iomem * base,u32 addr)559 static void serdes1g_write(void __iomem *base, u32 addr)
560 {
561 	u32 data;
562 
563 	writel(HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT |
564 	       HSIO_MCB_SERDES1G_CFG_ADDR(addr),
565 	       base + HSIO_MCB_SERDES1G_CFG);
566 
567 	do {
568 		data = readl(base + HSIO_MCB_SERDES1G_CFG);
569 	} while (data & HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT);
570 }
571 
serdes1g_setup(void __iomem * base,uint32_t addr,phy_interface_t interface)572 static void serdes1g_setup(void __iomem *base, uint32_t addr,
573 			   phy_interface_t interface)
574 {
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);
607 
608 	serdes1g_write(base, addr);
609 
610 	setbits_le32(base + HSIO_ANA_SERDES1G_COMMON_CFG,
611 		     HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST);
612 
613 	serdes1g_write(base, addr);
614 
615 	clrbits_le32(base + HSIO_DIG_SERDES1G_MISC_CFG,
616 		     HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST);
617 
618 	serdes1g_write(base, addr);
619 }
620 
ram_init(u32 val,void __iomem * addr)621 static int ram_init(u32 val, void __iomem *addr)
622 {
623 	writel(val, addr);
624 
625 	if (wait_for_bit_le32(addr, BIT(1), false, 2000, false)) {
626 		printf("Timeout in memory reset, reg = 0x%08x\n", val);
627 		return 1;
628 	}
629 
630 	return 0;
631 }
632 
jr2_switch_init(struct jr2_private * priv)633 static int jr2_switch_init(struct jr2_private *priv)
634 {
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);
640 
641 	/* Reset counters */
642 	writel(0x1, priv->regs[ANA_AC] + ANA_AC_STAT_GLOBAL_CFG_PORT_RESET);
643 	writel(0x1, priv->regs[ASM] + ASM_CFG_STAT_CFG);
644 
645 	/* Enable switch-core and queue system */
646 	writel(0x1, priv->regs[QSYS] + QSYS_SYSTEM_RESET_CFG);
647 
648 	return 0;
649 }
650 
jr2_switch_config(struct jr2_private * priv)651 static void jr2_switch_config(struct jr2_private *priv)
652 {
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));
657 
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);
661 }
662 
jr2_initialize(struct jr2_private * priv)663 static int jr2_initialize(struct jr2_private *priv)
664 {
665 	int ret, i;
666 
667 	/* Initialize switch memories, enable core */
668 	ret = jr2_switch_init(priv);
669 	if (ret)
670 		return ret;
671 
672 	jr2_switch_config(priv);
673 
674 	for (i = 0; i < MAX_PORT; i++)
675 		jr2_port_init(priv, i);
676 
677 	jr2_cpu_capture_setup(priv);
678 
679 	return 0;
680 }
681 
jr2_vlant_wait_for_completion(struct jr2_private * priv)682 static inline int jr2_vlant_wait_for_completion(struct jr2_private *priv)
683 {
684 	if (wait_for_bit_le32(priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL,
685 			      LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
686 			      false, 2000, false))
687 		return -ETIMEDOUT;
688 
689 	return 0;
690 }
691 
jr2_mac_table_add(struct jr2_private * priv,const unsigned char mac[ETH_ALEN],int pgid)692 static int jr2_mac_table_add(struct jr2_private *priv,
693 			     const unsigned char mac[ETH_ALEN], int pgid)
694 {
695 	u32 macl = 0, mach = 0;
696 
697 	/*
698 	 * Set the MAC address to handle and the vlan associated in a format
699 	 * understood by the hardware.
700 	 */
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;
708 
709 	writel(mach, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG0);
710 	writel(macl, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG1);
711 
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);
719 
720 	writel(LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
721 	       priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL);
722 
723 	return jr2_vlant_wait_for_completion(priv);
724 }
725 
jr2_write_hwaddr(struct udevice * dev)726 static int jr2_write_hwaddr(struct udevice *dev)
727 {
728 	struct jr2_private *priv = dev_get_priv(dev);
729 	struct eth_pdata *pdata = dev_get_plat(dev);
730 
731 	return jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
732 }
733 
serdes_setup(struct jr2_private * priv)734 static void serdes_setup(struct jr2_private *priv)
735 {
736 	size_t mask;
737 	int i = 0;
738 
739 	for (i = 0; i < MAX_PORT; ++i) {
740 		if (!priv->ports[i].bus || priv->ports[i].serdes_index == 0xff)
741 			continue;
742 
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);
747 		} else {
748 			mask >>= SERDES6G(0);
749 			serdes6g_setup(priv->regs[HSIO], mask,
750 				       priv->ports[i].phy_mode);
751 		}
752 	}
753 }
754 
jr2_start(struct udevice * dev)755 static int jr2_start(struct udevice *dev)
756 {
757 	struct jr2_private *priv = dev_get_priv(dev);
758 	struct eth_pdata *pdata = dev_get_plat(dev);
759 	const unsigned char mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff,
760 		0xff };
761 	int ret;
762 
763 	ret = jr2_initialize(priv);
764 	if (ret)
765 		return ret;
766 
767 	/* Set MAC address tables entries for CPU redirection */
768 	ret = jr2_mac_table_add(priv, mac, PGID_BROADCAST);
769 	if (ret)
770 		return ret;
771 
772 	ret = jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
773 	if (ret)
774 		return ret;
775 
776 	serdes_setup(priv);
777 
778 	return 0;
779 }
780 
jr2_stop(struct udevice * dev)781 static void jr2_stop(struct udevice *dev)
782 {
783 }
784 
jr2_send(struct udevice * dev,void * packet,int length)785 static int jr2_send(struct udevice *dev, void *packet, int length)
786 {
787 	struct jr2_private *priv = dev_get_priv(dev);
788 	u32 ifh[IFH_LEN];
789 	u32 *buf = packet;
790 
791 	memset(ifh, '\0', IFH_LEN);
792 
793 	/* Set DST PORT_MASK */
794 	ifh[0] = htonl(0);
795 	ifh[1] = htonl(0x1FFFFF);
796 	ifh[2] = htonl(~0);
797 	/* Set DST_MODE to INJECT and UPDATE_FCS */
798 	ifh[5] = htonl(0x4c0);
799 
800 	return mscc_send(priv->regs[QS], jr2_regs_qs,
801 			 ifh, IFH_LEN, buf, length);
802 }
803 
jr2_recv(struct udevice * dev,int flags,uchar ** packetp)804 static int jr2_recv(struct udevice *dev, int flags, uchar **packetp)
805 {
806 	struct jr2_private *priv = dev_get_priv(dev);
807 	u32 *rxbuf = (u32 *)net_rx_packets[0];
808 	int byte_cnt = 0;
809 
810 	byte_cnt = mscc_recv(priv->regs[QS], jr2_regs_qs, rxbuf, IFH_LEN,
811 			     false);
812 
813 	*packetp = net_rx_packets[0];
814 
815 	return byte_cnt;
816 }
817 
get_mdiobus(phys_addr_t base,unsigned long size)818 static struct mii_dev *get_mdiobus(phys_addr_t base, unsigned long size)
819 {
820 	int i = 0;
821 
822 	for (i = 0; i < JR2_MIIM_BUS_COUNT; ++i)
823 		if (miim[i].miim_base == base && miim[i].miim_size == size)
824 			return miim[i].bus;
825 
826 	return NULL;
827 }
828 
add_port_entry(struct jr2_private * priv,size_t index,size_t phy_addr,struct mii_dev * bus,u8 serdes_index,u8 phy_mode)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)
832 {
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;
837 }
838 
jr2_probe(struct udevice * dev)839 static int jr2_probe(struct udevice *dev)
840 {
841 	struct jr2_private *priv = dev_get_priv(dev);
842 	int i;
843 	int ret;
844 	struct resource res;
845 	fdt32_t faddr;
846 	phys_addr_t addr_base;
847 	unsigned long addr_size;
848 	ofnode eth_node, node, mdio_node;
849 	size_t phy_addr;
850 	struct mii_dev *bus;
851 	struct ofnode_phandle_args phandle;
852 	struct phy_device *phy;
853 
854 	if (!priv)
855 		return -EINVAL;
856 
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]) {
861 			debug
862 			    ("Error can't get regs base addresses for %s\n",
863 			     regs_names[i]);
864 			return -ENOMEM;
865 		}
866 	}
867 
868 	/* Initialize miim buses */
869 	memset(&miim, 0x0, sizeof(struct mscc_miim_dev) * JR2_MIIM_BUS_COUNT);
870 
871 	/* iterate all the ports and find out on which bus they are */
872 	i = 0;
873 	eth_node = dev_read_first_subnode(dev);
874 	for (node = ofnode_first_subnode(eth_node);
875 	     ofnode_valid(node);
876 	     node = ofnode_next_subnode(node)) {
877 		if (ofnode_read_resource(node, 0, &res))
878 			return -ENOMEM;
879 		i = res.start;
880 
881 		ret = ofnode_parse_phandle_with_args(node, "phy-handle", NULL,
882 						     0, 0, &phandle);
883 		if (ret)
884 			continue;
885 
886 		/* Get phy address on mdio bus */
887 		if (ofnode_read_resource(phandle.node, 0, &res))
888 			return -ENOMEM;
889 		phy_addr = res.start;
890 
891 		/* Get mdio node */
892 		mdio_node = ofnode_get_parent(phandle.node);
893 
894 		if (ofnode_read_resource(mdio_node, 0, &res))
895 			return -ENOMEM;
896 		faddr = cpu_to_fdt32(res.start);
897 
898 		addr_base = ofnode_translate_address(mdio_node, &faddr);
899 		addr_size = res.end - res.start;
900 
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,
905 						  addr_size);
906 
907 		/* Connect mdio bus with the port */
908 		bus = get_mdiobus(addr_base, addr_size);
909 
910 		/* Get serdes info */
911 		ret = ofnode_parse_phandle_with_args(node, "phys", NULL,
912 						     3, 0, &phandle);
913 		if (ret)
914 			return -ENOMEM;
915 
916 		add_port_entry(priv, i, phy_addr, bus, phandle.args[1],
917 			       phandle.args[2]);
918 	}
919 
920 	for (i = 0; i < MAX_PORT; i++) {
921 		if (!priv->ports[i].bus)
922 			continue;
923 
924 		phy = phy_connect(priv->ports[i].bus,
925 				  priv->ports[i].phy_addr, dev,
926 				  PHY_INTERFACE_MODE_NONE);
927 		if (phy)
928 			board_phy_config(phy);
929 	}
930 
931 	return 0;
932 }
933 
jr2_remove(struct udevice * dev)934 static int jr2_remove(struct udevice *dev)
935 {
936 	struct jr2_private *priv = dev_get_priv(dev);
937 	int i;
938 
939 	for (i = 0; i < JR2_MIIM_BUS_COUNT; i++) {
940 		mdio_unregister(priv->bus[i]);
941 		mdio_free(priv->bus[i]);
942 	}
943 
944 	return 0;
945 }
946 
947 static const struct eth_ops jr2_ops = {
948 	.start        = jr2_start,
949 	.stop         = jr2_stop,
950 	.send         = jr2_send,
951 	.recv         = jr2_recv,
952 	.write_hwaddr = jr2_write_hwaddr,
953 };
954 
955 static const struct udevice_id mscc_jr2_ids[] = {
956 	{.compatible = "mscc,vsc7454-switch" },
957 	{ /* Sentinel */ }
958 };
959 
960 U_BOOT_DRIVER(jr2) = {
961 	.name				= "jr2-switch",
962 	.id				= UCLASS_ETH,
963 	.of_match			= mscc_jr2_ids,
964 	.probe				= jr2_probe,
965 	.remove				= jr2_remove,
966 	.ops				= &jr2_ops,
967 	.priv_auto		= sizeof(struct jr2_private),
968 	.plat_auto	= sizeof(struct eth_pdata),
969 };
970