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