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