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", "gcb", "icpu",
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 	GCB,
256 	ICPU,
257 };
258 
259 #define JR2_MIIM_BUS_COUNT 3
260 
261 struct jr2_phy_port_t {
262 	size_t phy_addr;
263 	struct mii_dev *bus;
264 	u8 serdes_index;
265 	u8 phy_mode;
266 };
267 
268 struct jr2_private {
269 	void __iomem *regs[REGS_NAMES_COUNT];
270 	struct mii_dev *bus[JR2_MIIM_BUS_COUNT];
271 	struct jr2_phy_port_t ports[MAX_PORT];
272 };
273 
274 static const unsigned long jr2_regs_qs[] = {
275 	[MSCC_QS_XTR_RD] = 0x8,
276 	[MSCC_QS_XTR_FLUSH] = 0x18,
277 	[MSCC_QS_XTR_DATA_PRESENT] = 0x1c,
278 	[MSCC_QS_INJ_WR] = 0x2c,
279 	[MSCC_QS_INJ_CTRL] = 0x34,
280 };
281 
282 static struct mscc_miim_dev miim[JR2_MIIM_BUS_COUNT];
283 static int miim_count = -1;
284 
jr2_cpu_capture_setup(struct jr2_private * priv)285 static void jr2_cpu_capture_setup(struct jr2_private *priv)
286 {
287 	/* ASM: No preamble and IFH prefix on CPU injected frames */
288 	writel(ASM_CFG_PORT_NO_PREAMBLE_ENA |
289 	       ASM_CFG_PORT_INJ_FORMAT_CFG(1),
290 	       priv->regs[ASM] + ASM_CFG_PORT(CPU_PORT));
291 
292 	/* Set Manual injection via DEVCPU_QS registers for CPU queue 0 */
293 	writel(0x5, priv->regs[QS] + QS_INJ_GRP_CFG(0));
294 
295 	/* Set Manual extraction via DEVCPU_QS registers for CPU queue 0 */
296 	writel(0x7, priv->regs[QS] + QS_XTR_GRP_CFG(0));
297 
298 	/* Enable CPU port for any frame transfer */
299 	setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(CPU_PORT),
300 		     QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA);
301 
302 	/* Send a copy to CPU when found as forwarding entry */
303 	setbits_le32(priv->regs[ANA_L2] + ANA_L2_COMMON_FWD_CFG,
304 		     ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA);
305 }
306 
jr2_port_init(struct jr2_private * priv,int port)307 static void jr2_port_init(struct jr2_private *priv, int port)
308 {
309 	void __iomem *regs = priv->regs[port];
310 
311 	/* Enable PCS */
312 	writel(DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA,
313 	       regs + DEV_PCS1G_CFG_PCS1G_CFG);
314 
315 	/* Disable Signal Detect */
316 	writel(0, regs + DEV_PCS1G_CFG_PCS1G_SD);
317 
318 	/* Enable MAC RX and TX */
319 	writel(DEV_MAC_CFG_MAC_ENA_RX_ENA |
320 	       DEV_MAC_CFG_MAC_ENA_TX_ENA,
321 	       regs + DEV_MAC_CFG_MAC_ENA);
322 
323 	/* Clear sgmii_mode_ena */
324 	writel(0, regs + DEV_PCS1G_CFG_PCS1G_MODE);
325 
326 	/*
327 	 * Clear sw_resolve_ena(bit 0) and set adv_ability to
328 	 * something meaningful just in case
329 	 */
330 	writel(DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(0x20),
331 	       regs + DEV_PCS1G_CFG_PCS1G_ANEG);
332 
333 	/* Set MAC IFG Gaps */
334 	writel(DEV_MAC_CFG_MAC_IFG_TX_IFG(4) |
335 	       DEV_MAC_CFG_MAC_IFG_RX_IFG1(5) |
336 	       DEV_MAC_CFG_MAC_IFG_RX_IFG2(1),
337 	       regs + DEV_MAC_CFG_MAC_IFG);
338 
339 	/* Set link speed and release all resets */
340 	writel(DEV_DEV_CFG_DEV_RST_CTRL_SPEED_SEL(2),
341 	       regs + DEV_DEV_CFG_DEV_RST_CTRL);
342 
343 	/* Make VLAN aware for CPU traffic */
344 	writel(ANA_CL_PORT_VLAN_CFG_AWARE_ENA |
345 	       ANA_CL_PORT_VLAN_CFG_POP_CNT(1) |
346 	       MAC_VID,
347 	       priv->regs[ANA_CL] + ANA_CL_PORT_VLAN_CFG(port));
348 
349 	/* Enable CPU port for any frame transfer */
350 	setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(port),
351 		     QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA);
352 }
353 
serdes6g_write(void __iomem * base,u32 addr)354 static void serdes6g_write(void __iomem *base, u32 addr)
355 {
356 	u32 data;
357 
358 	writel(HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT |
359 	       HSIO_MCB_SERDES6G_CFG_ADDR(addr),
360 	       base + HSIO_MCB_SERDES6G_CFG);
361 
362 	do {
363 		data = readl(base + HSIO_MCB_SERDES6G_CFG);
364 	} while (data & HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT);
365 }
366 
serdes6g_setup(void __iomem * base,uint32_t addr,phy_interface_t interface)367 static void serdes6g_setup(void __iomem *base, uint32_t addr,
368 			   phy_interface_t interface)
369 {
370 	u32 ib_if_mode = 0;
371 	u32 ib_qrate = 0;
372 	u32 ib1_tsdet = 0;
373 	u32 ob_lev = 0;
374 	u32 ob_ena_cas = 0;
375 	u32 ob_ena1v_mode = 0;
376 	u32 des_bw_ana = 0;
377 	u32 pll_fsm_ctrl_data = 0;
378 
379 	switch (interface) {
380 	case PHY_INTERFACE_MODE_SGMII:
381 		ib_if_mode = 1;
382 		ib_qrate = 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_OB_CFG_RESISTOR_CTRL(1) |
406 	       HSIO_ANA_SERDES6G_OB_CFG_SR(7) |
407 	       HSIO_ANA_SERDES6G_OB_CFG_SR_H |
408 	       HSIO_ANA_SERDES6G_OB_CFG_ENA1V_MODE(ob_ena1v_mode) |
409 	       HSIO_ANA_SERDES6G_OB_CFG_POL, base + HSIO_ANA_SERDES6G_OB_CFG);
410 
411 	writel(HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(3),
412 	       base + HSIO_ANA_SERDES6G_COMMON_CFG);
413 	writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(120) |
414 	       HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
415 	       base + HSIO_ANA_SERDES6G_PLL_CFG);
416 	writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
417 	       HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
418 	       HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
419 	       HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
420 	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
421 	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
422 	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
423 	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
424 	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
425 	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(7) |
426 	       HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
427 	       HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
428 	       HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
429 	       HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
430 	       HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
431 	       base + HSIO_ANA_SERDES6G_IB_CFG);
432 	writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
433 	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
434 	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
435 	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
436 	       HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
437 	       HSIO_ANA_SERDES6G_IB_CFG1_TSDET(3) |
438 	       HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
439 	       base + HSIO_ANA_SERDES6G_IB_CFG1);
440 
441 	writel(HSIO_ANA_SERDES6G_IB_CFG2_UREG(4) |
442 	       HSIO_ANA_SERDES6G_IB_CFG2_UMAX(2) |
443 	       HSIO_ANA_SERDES6G_IB_CFG2_TCALV(12) |
444 	       HSIO_ANA_SERDES6G_IB_CFG2_OCALS(32) |
445 	       HSIO_ANA_SERDES6G_IB_CFG2_OINFS(7) |
446 	       HSIO_ANA_SERDES6G_IB_CFG2_OINFI(0x1f) |
447 	       HSIO_ANA_SERDES6G_IB_CFG2_TINFV(3),
448 	       base + HSIO_ANA_SERDES6G_IB_CFG2);
449 
450 	writel(HSIO_ANA_SERDES6G_IB_CFG3_INI_OFFSET(0x1f) |
451 	       HSIO_ANA_SERDES6G_IB_CFG3_INI_LP(1) |
452 	       HSIO_ANA_SERDES6G_IB_CFG3_INI_MID(0x1f),
453 	       base + HSIO_ANA_SERDES6G_IB_CFG3);
454 
455 	writel(HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST,
456 	       base + HSIO_DIG_SERDES6G_MISC_CFG);
457 
458 	serdes6g_write(base, addr);
459 
460 	writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
461 	       HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
462 	       HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
463 	       HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
464 	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
465 	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
466 	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
467 	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
468 	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
469 	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(0) |
470 	       HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
471 	       HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
472 	       HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
473 	       HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
474 	       HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
475 	       base + HSIO_ANA_SERDES6G_IB_CFG);
476 	writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
477 	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
478 	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
479 	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
480 	       HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
481 	       HSIO_ANA_SERDES6G_IB_CFG1_TSDET(16) |
482 	       HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
483 	       base + HSIO_ANA_SERDES6G_IB_CFG1);
484 
485 	writel(0x0, base + HSIO_ANA_SERDES6G_SER_CFG);
486 	writel(HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(ib_if_mode) |
487 	       HSIO_ANA_SERDES6G_COMMON_CFG_QRATE(ib_qrate) |
488 	       HSIO_ANA_SERDES6G_COMMON_CFG_ENA_LANE |
489 	       HSIO_ANA_SERDES6G_COMMON_CFG_SYS_RST,
490 	       base + HSIO_ANA_SERDES6G_COMMON_CFG);
491 	writel(HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST,
492 	       base + HSIO_DIG_SERDES6G_MISC_CFG);
493 
494 	writel(HSIO_ANA_SERDES6G_OB_CFG_RESISTOR_CTRL(1) |
495 	       HSIO_ANA_SERDES6G_OB_CFG_SR(7) |
496 	       HSIO_ANA_SERDES6G_OB_CFG_SR_H |
497 	       HSIO_ANA_SERDES6G_OB_CFG_ENA1V_MODE(ob_ena1v_mode) |
498 	       HSIO_ANA_SERDES6G_OB_CFG_POL, base + HSIO_ANA_SERDES6G_OB_CFG);
499 	writel(HSIO_ANA_SERDES6G_OB_CFG1_LEV(ob_lev) |
500 	       HSIO_ANA_SERDES6G_OB_CFG1_ENA_CAS(ob_ena_cas),
501 	       base + HSIO_ANA_SERDES6G_OB_CFG1);
502 
503 	writel(HSIO_ANA_SERDES6G_DES_CFG_BW_ANA(des_bw_ana) |
504 	       HSIO_ANA_SERDES6G_DES_CFG_BW_HYST(5) |
505 	       HSIO_ANA_SERDES6G_DES_CFG_MBTR_CTRL(2) |
506 	       HSIO_ANA_SERDES6G_DES_CFG_PHS_CTRL(6),
507 	       base + HSIO_ANA_SERDES6G_DES_CFG);
508 	writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(pll_fsm_ctrl_data) |
509 	       HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
510 	       base + HSIO_ANA_SERDES6G_PLL_CFG);
511 
512 	serdes6g_write(base, addr);
513 
514 	/* set pll_fsm_ena = 1 */
515 	writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_ENA |
516 	       HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(pll_fsm_ctrl_data) |
517 	       HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3),
518 	       base + HSIO_ANA_SERDES6G_PLL_CFG);
519 
520 	serdes6g_write(base, addr);
521 
522 	/* wait 20ms for pll bringup */
523 	mdelay(20);
524 
525 	/* start IB calibration by setting ib_cal_ena and clearing lane_rst */
526 	writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
527 	       HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
528 	       HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
529 	       HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(1) |
530 	       HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
531 	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
532 	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
533 	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
534 	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
535 	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
536 	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(0) |
537 	       HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
538 	       HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
539 	       HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
540 	       HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
541 	       HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
542 	       base + HSIO_ANA_SERDES6G_IB_CFG);
543 	writel(0x0, base + HSIO_DIG_SERDES6G_MISC_CFG);
544 
545 	serdes6g_write(base, addr);
546 
547 	/* wait 60 for calibration */
548 	mdelay(60);
549 
550 	/* set ib_tsdet and ib_reg_pat_sel_offset back to correct values */
551 	writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA |
552 	       HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA |
553 	       HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA |
554 	       HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(1) |
555 	       HSIO_ANA_SERDES6G_IB_CFG_CONCUR |
556 	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA |
557 	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) |
558 	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) |
559 	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) |
560 	       HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) |
561 	       HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(7) |
562 	       HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) |
563 	       HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) |
564 	       HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) |
565 	       HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL |
566 	       HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1),
567 	       base + HSIO_ANA_SERDES6G_IB_CFG);
568 	writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET |
569 	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP |
570 	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID |
571 	       HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP |
572 	       HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) |
573 	       HSIO_ANA_SERDES6G_IB_CFG1_TSDET(ib1_tsdet) |
574 	       HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8),
575 	       base + HSIO_ANA_SERDES6G_IB_CFG1);
576 
577 	serdes6g_write(base, addr);
578 }
579 
serdes1g_write(void __iomem * base,u32 addr)580 static void serdes1g_write(void __iomem *base, u32 addr)
581 {
582 	u32 data;
583 
584 	writel(HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT |
585 	       HSIO_MCB_SERDES1G_CFG_ADDR(addr),
586 	       base + HSIO_MCB_SERDES1G_CFG);
587 
588 	do {
589 		data = readl(base + HSIO_MCB_SERDES1G_CFG);
590 	} while (data & HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT);
591 }
592 
serdes1g_setup(void __iomem * base,uint32_t addr,phy_interface_t interface)593 static void serdes1g_setup(void __iomem *base, uint32_t addr,
594 			   phy_interface_t interface)
595 {
596 	writel(0x0, base + HSIO_ANA_SERDES1G_SER_CFG);
597 	writel(0x0, base + HSIO_DIG_SERDES1G_TP_CFG);
598 	writel(0x0, base + HSIO_DIG_SERDES1G_DFT_CFG0);
599 	writel(HSIO_ANA_SERDES1G_OB_CFG_RESISTOR_CTRL(1) |
600 	       HSIO_ANA_SERDES1G_OB_CFG_VCM_CTRL(4) |
601 	       HSIO_ANA_SERDES1G_OB_CFG_CMM_BIAS_CTRL(2) |
602 	       HSIO_ANA_SERDES1G_OB_CFG_AMP_CTRL(12) |
603 	       HSIO_ANA_SERDES1G_OB_CFG_SLP(3),
604 	       base + HSIO_ANA_SERDES1G_OB_CFG);
605 	writel(HSIO_ANA_SERDES1G_IB_CFG_RESISTOR_CTRL(13) |
606 	       HSIO_ANA_SERDES1G_IB_CFG_EQ_GAIN(2) |
607 	       HSIO_ANA_SERDES1G_IB_CFG_ENA_OFFSET_COMP |
608 	       HSIO_ANA_SERDES1G_IB_CFG_ENA_DETLEV |
609 	       HSIO_ANA_SERDES1G_IB_CFG_ENA_CMV_TERM |
610 	       HSIO_ANA_SERDES1G_IB_CFG_DET_LEV(3) |
611 	       HSIO_ANA_SERDES1G_IB_CFG_ACJTAG_HYST(1),
612 	       base + HSIO_ANA_SERDES1G_IB_CFG);
613 	writel(HSIO_ANA_SERDES1G_DES_CFG_BW_HYST(7) |
614 	       HSIO_ANA_SERDES1G_DES_CFG_BW_ANA(6) |
615 	       HSIO_ANA_SERDES1G_DES_CFG_MBTR_CTRL(2) |
616 	       HSIO_ANA_SERDES1G_DES_CFG_PHS_CTRL(6),
617 	       base + HSIO_ANA_SERDES1G_DES_CFG);
618 	writel(HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST,
619 	       base + HSIO_DIG_SERDES1G_MISC_CFG);
620 	writel(HSIO_ANA_SERDES1G_PLL_CFG_FSM_ENA |
621 	       HSIO_ANA_SERDES1G_PLL_CFG_FSM_CTRL_DATA(0xc8) |
622 	       HSIO_ANA_SERDES1G_PLL_CFG_ENA_RC_DIV2,
623 	       base + HSIO_ANA_SERDES1G_PLL_CFG);
624 	writel(HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE |
625 	       HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE |
626 	       HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST,
627 	       base + HSIO_ANA_SERDES1G_COMMON_CFG);
628 
629 	serdes1g_write(base, addr);
630 
631 	setbits_le32(base + HSIO_ANA_SERDES1G_COMMON_CFG,
632 		     HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST);
633 
634 	serdes1g_write(base, addr);
635 
636 	clrbits_le32(base + HSIO_DIG_SERDES1G_MISC_CFG,
637 		     HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST);
638 
639 	serdes1g_write(base, addr);
640 }
641 
ram_init(u32 val,void __iomem * addr)642 static int ram_init(u32 val, void __iomem *addr)
643 {
644 	writel(val, addr);
645 
646 	if (wait_for_bit_le32(addr, BIT(1), false, 2000, false)) {
647 		printf("Timeout in memory reset, reg = 0x%08x\n", val);
648 		return 1;
649 	}
650 
651 	return 0;
652 }
653 
jr2_switch_init(struct jr2_private * priv)654 static int jr2_switch_init(struct jr2_private *priv)
655 {
656 	/* Initialize memories */
657 	ram_init(0x3, priv->regs[QSYS] + QSYS_RAM_CTRL_RAM_INIT);
658 	ram_init(0x3, priv->regs[ASM] + ASM_RAM_CTRL_RAM_INIT);
659 	ram_init(0x3, priv->regs[ANA_AC] + ANA_AC_RAM_CTRL_RAM_INIT);
660 	ram_init(0x3, priv->regs[REW] + REW_RAM_CTRL_RAM_INIT);
661 
662 	/* Reset counters */
663 	writel(0x1, priv->regs[ANA_AC] + ANA_AC_STAT_GLOBAL_CFG_PORT_RESET);
664 	writel(0x1, priv->regs[ASM] + ASM_CFG_STAT_CFG);
665 
666 	/* Enable switch-core and queue system */
667 	writel(0x1, priv->regs[QSYS] + QSYS_SYSTEM_RESET_CFG);
668 
669 	return 0;
670 }
671 
jr2_switch_config(struct jr2_private * priv)672 static void jr2_switch_config(struct jr2_private *priv)
673 {
674 	writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(0));
675 	writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(1));
676 	writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(2));
677 	writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(3));
678 
679 	writel(readl(priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL) |
680 	       QSYS_CALCFG_CAL_CTRL_CAL_MODE(8),
681 	       priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL);
682 }
683 
jr2_initialize(struct jr2_private * priv)684 static int jr2_initialize(struct jr2_private *priv)
685 {
686 	int ret, i;
687 
688 	/* Initialize switch memories, enable core */
689 	ret = jr2_switch_init(priv);
690 	if (ret)
691 		return ret;
692 
693 	jr2_switch_config(priv);
694 
695 	for (i = 0; i < MAX_PORT; i++)
696 		jr2_port_init(priv, i);
697 
698 	jr2_cpu_capture_setup(priv);
699 
700 	return 0;
701 }
702 
jr2_vlant_wait_for_completion(struct jr2_private * priv)703 static inline int jr2_vlant_wait_for_completion(struct jr2_private *priv)
704 {
705 	if (wait_for_bit_le32(priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL,
706 			      LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
707 			      false, 2000, false))
708 		return -ETIMEDOUT;
709 
710 	return 0;
711 }
712 
jr2_mac_table_add(struct jr2_private * priv,const unsigned char mac[ETH_ALEN],int pgid)713 static int jr2_mac_table_add(struct jr2_private *priv,
714 			     const unsigned char mac[ETH_ALEN], int pgid)
715 {
716 	u32 macl = 0, mach = 0;
717 
718 	/*
719 	 * Set the MAC address to handle and the vlan associated in a format
720 	 * understood by the hardware.
721 	 */
722 	mach |= MAC_VID << 16;
723 	mach |= ((u32)mac[0]) << 8;
724 	mach |= ((u32)mac[1]) << 0;
725 	macl |= ((u32)mac[2]) << 24;
726 	macl |= ((u32)mac[3]) << 16;
727 	macl |= ((u32)mac[4]) << 8;
728 	macl |= ((u32)mac[5]) << 0;
729 
730 	writel(mach, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG0);
731 	writel(macl, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG1);
732 
733 	writel(LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_ADDR(pgid) |
734 	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_TYPE(0x3) |
735 	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_COPY |
736 	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_QU(0) |
737 	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_VLD |
738 	       LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_LOCKED,
739 	       priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG2);
740 
741 	writel(LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT,
742 	       priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL);
743 
744 	return jr2_vlant_wait_for_completion(priv);
745 }
746 
jr2_write_hwaddr(struct udevice * dev)747 static int jr2_write_hwaddr(struct udevice *dev)
748 {
749 	struct jr2_private *priv = dev_get_priv(dev);
750 	struct eth_pdata *pdata = dev_get_plat(dev);
751 
752 	return jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
753 }
754 
serdes_setup(struct jr2_private * priv)755 static void serdes_setup(struct jr2_private *priv)
756 {
757 	size_t mask;
758 	int i = 0;
759 
760 	for (i = 0; i < MAX_PORT; ++i) {
761 		if (!priv->ports[i].bus || priv->ports[i].serdes_index == 0xff)
762 			continue;
763 
764 		mask = BIT(priv->ports[i].serdes_index);
765 		if (priv->ports[i].serdes_index < SERDES1G_MAX) {
766 			serdes1g_setup(priv->regs[HSIO], mask,
767 				       priv->ports[i].phy_mode);
768 		} else {
769 			mask >>= SERDES6G(0);
770 			serdes6g_setup(priv->regs[HSIO], mask,
771 				       priv->ports[i].phy_mode);
772 		}
773 	}
774 }
775 
jr2_start(struct udevice * dev)776 static int jr2_start(struct udevice *dev)
777 {
778 	struct jr2_private *priv = dev_get_priv(dev);
779 	struct eth_pdata *pdata = dev_get_plat(dev);
780 	const unsigned char mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff,
781 		0xff };
782 	int ret;
783 
784 	ret = jr2_initialize(priv);
785 	if (ret)
786 		return ret;
787 
788 	/* Set MAC address tables entries for CPU redirection */
789 	ret = jr2_mac_table_add(priv, mac, PGID_BROADCAST);
790 	if (ret)
791 		return ret;
792 
793 	ret = jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST);
794 	if (ret)
795 		return ret;
796 
797 	serdes_setup(priv);
798 
799 	return 0;
800 }
801 
jr2_stop(struct udevice * dev)802 static void jr2_stop(struct udevice *dev)
803 {
804 }
805 
jr2_send(struct udevice * dev,void * packet,int length)806 static int jr2_send(struct udevice *dev, void *packet, int length)
807 {
808 	struct jr2_private *priv = dev_get_priv(dev);
809 	u32 ifh[IFH_LEN];
810 	u32 *buf = packet;
811 
812 	memset(ifh, '\0', IFH_LEN);
813 
814 	/* Set DST PORT_MASK */
815 	ifh[0] = htonl(0);
816 	ifh[1] = htonl(0x1FFFFF);
817 	ifh[2] = htonl(~0);
818 	/* Set DST_MODE to INJECT and UPDATE_FCS */
819 	ifh[5] = htonl(0x4c0);
820 
821 	return mscc_send(priv->regs[QS], jr2_regs_qs,
822 			 ifh, IFH_LEN, buf, length);
823 }
824 
jr2_recv(struct udevice * dev,int flags,uchar ** packetp)825 static int jr2_recv(struct udevice *dev, int flags, uchar **packetp)
826 {
827 	struct jr2_private *priv = dev_get_priv(dev);
828 	u32 *rxbuf = (u32 *)net_rx_packets[0];
829 	int byte_cnt = 0;
830 
831 	byte_cnt = mscc_recv(priv->regs[QS], jr2_regs_qs, rxbuf, IFH_LEN,
832 			     false);
833 
834 	*packetp = net_rx_packets[0];
835 
836 	return byte_cnt;
837 }
838 
get_mdiobus(phys_addr_t base,unsigned long size)839 static struct mii_dev *get_mdiobus(phys_addr_t base, unsigned long size)
840 {
841 	int i = 0;
842 
843 	for (i = 0; i < JR2_MIIM_BUS_COUNT; ++i)
844 		if (miim[i].miim_base == base && miim[i].miim_size == size)
845 			return miim[i].bus;
846 
847 	return NULL;
848 }
849 
add_port_entry(struct jr2_private * priv,size_t index,size_t phy_addr,struct mii_dev * bus,u8 serdes_index,u8 phy_mode)850 static void add_port_entry(struct jr2_private *priv, size_t index,
851 			   size_t phy_addr, struct mii_dev *bus,
852 			   u8 serdes_index, u8 phy_mode)
853 {
854 	priv->ports[index].phy_addr = phy_addr;
855 	priv->ports[index].bus = bus;
856 	priv->ports[index].serdes_index = serdes_index;
857 	priv->ports[index].phy_mode = phy_mode;
858 }
859 
jr2_probe(struct udevice * dev)860 static int jr2_probe(struct udevice *dev)
861 {
862 	struct jr2_private *priv = dev_get_priv(dev);
863 	int i;
864 	int ret;
865 	struct resource res;
866 	phys_addr_t addr_base;
867 	unsigned long addr_size;
868 	ofnode eth_node, node, mdio_node;
869 	size_t phy_addr;
870 	struct mii_dev *bus;
871 	struct ofnode_phandle_args phandle;
872 	struct phy_device *phy;
873 	u32 val;
874 
875 	if (!priv)
876 		return -EINVAL;
877 
878 	/* Get registers and map them to the private structure */
879 	for (i = 0; i < ARRAY_SIZE(regs_names); i++) {
880 		priv->regs[i] = dev_remap_addr_name(dev, regs_names[i]);
881 		if (!priv->regs[i]) {
882 			debug
883 			    ("Error can't get regs base addresses for %s\n",
884 			     regs_names[i]);
885 			return -ENOMEM;
886 		}
887 	}
888 
889 	val = readl(priv->regs[ICPU] + ICPU_RESET);
890 	val |= ICPU_RESET_CORE_RST_PROTECT;
891 	writel(val, priv->regs[ICPU] + ICPU_RESET);
892 
893 	val = readl(priv->regs[GCB] + PERF_SOFT_RST);
894 	val |= PERF_SOFT_RST_SOFT_SWC_RST;
895 	writel(val, priv->regs[GCB] + PERF_SOFT_RST);
896 
897 	while (readl(priv->regs[GCB] + PERF_SOFT_RST) & PERF_SOFT_RST_SOFT_SWC_RST)
898 		;
899 
900 	/* Initialize miim buses */
901 	memset(&miim, 0x0, sizeof(struct mscc_miim_dev) * JR2_MIIM_BUS_COUNT);
902 
903 	/* iterate all the ports and find out on which bus they are */
904 	i = 0;
905 	eth_node = dev_read_first_subnode(dev);
906 	for (node = ofnode_first_subnode(eth_node);
907 	     ofnode_valid(node);
908 	     node = ofnode_next_subnode(node)) {
909 		if (ofnode_read_resource(node, 0, &res))
910 			return -ENOMEM;
911 		i = res.start;
912 
913 		ret = ofnode_parse_phandle_with_args(node, "phy-handle", NULL,
914 						     0, 0, &phandle);
915 		if (ret)
916 			continue;
917 
918 		/* Get phy address on mdio bus */
919 		if (ofnode_read_resource(phandle.node, 0, &res))
920 			return -ENOMEM;
921 		phy_addr = res.start;
922 
923 		/* Get mdio node */
924 		mdio_node = ofnode_get_parent(phandle.node);
925 
926 		if (ofnode_read_resource(mdio_node, 0, &res))
927 			return -ENOMEM;
928 
929 		addr_base = res.start;
930 		addr_size = res.end - res.start;
931 
932 		/* If the bus is new then create a new bus */
933 		if (!get_mdiobus(addr_base, addr_size))
934 			priv->bus[miim_count] =
935 				mscc_mdiobus_init(miim, &miim_count, addr_base,
936 						  addr_size);
937 
938 		/* Connect mdio bus with the port */
939 		bus = get_mdiobus(addr_base, addr_size);
940 
941 		/* Get serdes info */
942 		ret = ofnode_parse_phandle_with_args(node, "phys", NULL,
943 						     3, 0, &phandle);
944 		if (ret)
945 			return -ENOMEM;
946 
947 		add_port_entry(priv, i, phy_addr, bus, phandle.args[1],
948 			       phandle.args[2]);
949 	}
950 
951 	for (i = 0; i < MAX_PORT; i++) {
952 		if (!priv->ports[i].bus)
953 			continue;
954 
955 		phy = phy_connect(priv->ports[i].bus,
956 				  priv->ports[i].phy_addr, dev,
957 				  PHY_INTERFACE_MODE_NONE);
958 		if (phy)
959 			board_phy_config(phy);
960 	}
961 
962 	return 0;
963 }
964 
jr2_remove(struct udevice * dev)965 static int jr2_remove(struct udevice *dev)
966 {
967 	struct jr2_private *priv = dev_get_priv(dev);
968 	int i;
969 
970 	for (i = 0; i < JR2_MIIM_BUS_COUNT; i++) {
971 		mdio_unregister(priv->bus[i]);
972 		mdio_free(priv->bus[i]);
973 	}
974 
975 	return 0;
976 }
977 
978 static const struct eth_ops jr2_ops = {
979 	.start        = jr2_start,
980 	.stop         = jr2_stop,
981 	.send         = jr2_send,
982 	.recv         = jr2_recv,
983 	.write_hwaddr = jr2_write_hwaddr,
984 };
985 
986 static const struct udevice_id mscc_jr2_ids[] = {
987 	{.compatible = "mscc,vsc7454-switch" },
988 	{ /* Sentinel */ }
989 };
990 
991 U_BOOT_DRIVER(jr2) = {
992 	.name				= "jr2-switch",
993 	.id				= UCLASS_ETH,
994 	.of_match			= mscc_jr2_ids,
995 	.probe				= jr2_probe,
996 	.remove				= jr2_remove,
997 	.ops				= &jr2_ops,
998 	.priv_auto		= sizeof(struct jr2_private),
999 	.plat_auto	= sizeof(struct eth_pdata),
1000 };
1001