dm: core: Add address translation in fdt_get_resource
[platform/kernel/u-boot.git] / drivers / net / mscc_eswitch / jr2_switch.c
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
802 static void jr2_stop(struct udevice *dev)
803 {
804 }
805
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
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
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
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
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
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 };