Merge tag 'efi-2020-07-rc6' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi
[oweals/u-boot.git] / drivers / net / mscc_eswitch / luton_switch.c
1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2 /*
3  * Copyright (c) 2019 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/io.h>
15 #include <linux/ioport.h>
16 #include <miiphy.h>
17 #include <net.h>
18 #include <wait_bit.h>
19
20 #include "mscc_xfer.h"
21 #include "mscc_mac_table.h"
22 #include "mscc_miim.h"
23
24 #define ANA_PORT_VLAN_CFG(x)            (0x00 + 0x80 * (x))
25 #define         ANA_PORT_VLAN_CFG_AWARE_ENA     BIT(20)
26 #define         ANA_PORT_VLAN_CFG_POP_CNT(x)    ((x) << 18)
27 #define ANA_PORT_CPU_FWD_CFG(x)         (0x50 + 0x80 * (x))
28 #define         ANA_PORT_CPU_FWD_CFG_SRC_COPY_ENA       BIT(1)
29 #define ANA_PORT_PORT_CFG(x)            (0x60 + 0x80 * (x))
30 #define         ANA_PORT_PORT_CFG_RECV_ENA      BIT(5)
31 #define ANA_PGID(x)                     (0x1000 + 4 * (x))
32
33 #define SYS_FRM_AGING                   0x8300
34
35 #define SYS_SYSTEM_RST_CFG              0x81b0
36 #define         SYS_SYSTEM_RST_MEM_INIT         BIT(0)
37 #define         SYS_SYSTEM_RST_MEM_ENA          BIT(1)
38 #define         SYS_SYSTEM_RST_CORE_ENA         BIT(2)
39 #define SYS_PORT_MODE(x)                (0x81bc + 0x4 * (x))
40 #define         SYS_PORT_MODE_INCL_INJ_HDR      BIT(0)
41 #define SYS_SWITCH_PORT_MODE(x)         (0x8294 + 0x4 * (x))
42 #define         SYS_SWITCH_PORT_MODE_PORT_ENA   BIT(3)
43 #define SYS_EGR_NO_SHARING              0x8378
44 #define SYS_SCH_CPU                     0x85a0
45
46 #define REW_PORT_CFG(x)                 (0x8 + 0x80 * (x))
47 #define         REW_PORT_CFG_IFH_INSERT_ENA     BIT(7)
48
49 #define GCB_DEVCPU_RST_SOFT_CHIP_RST    0x90
50 #define         GCB_DEVCPU_RST_SOFT_CHIP_RST_SOFT_PHY   BIT(1)
51 #define GCB_MISC_STAT                   0x11c
52 #define         GCB_MISC_STAT_PHY_READY                 BIT(3)
53
54 #define QS_XTR_MAP(x)                   (0x10 + 4 * (x))
55 #define         QS_XTR_MAP_GRP                  BIT(4)
56 #define         QS_XTR_MAP_ENA                  BIT(0)
57
58 #define HSIO_PLL5G_CFG_PLL5G_CFG2       0x8
59
60 #define HSIO_RCOMP_CFG_CFG0             0x20
61 #define         HSIO_RCOMP_CFG_CFG0_MODE_SEL(x)                 ((x) << 8)
62 #define         HSIO_RCOMP_CFG_CFG0_RUN_CAL                     BIT(12)
63 #define HSIO_RCOMP_STATUS               0x24
64 #define         HSIO_RCOMP_STATUS_BUSY                          BIT(12)
65 #define         HSIO_RCOMP_STATUS_RCOMP_M                       GENMASK(3, 0)
66 #define HSIO_SERDES6G_ANA_CFG_DES_CFG   0x64
67 #define         HSIO_SERDES6G_ANA_CFG_DES_CFG_BW_ANA(x)         ((x) << 1)
68 #define         HSIO_SERDES6G_ANA_CFG_DES_CFG_BW_HYST(x)        ((x) << 5)
69 #define         HSIO_SERDES6G_ANA_CFG_DES_CFG_MBTR_CTRL(x)      ((x) << 10)
70 #define         HSIO_SERDES6G_ANA_CFG_DES_CFG_PHS_CTRL(x)       ((x) << 13)
71 #define HSIO_SERDES6G_ANA_CFG_IB_CFG    0x68
72 #define         HSIO_SERDES6G_ANA_CFG_IB_CFG_RESISTOR_CTRL(x)   (x)
73 #define         HSIO_SERDES6G_ANA_CFG_IB_CFG_VBCOM(x)           ((x) << 4)
74 #define         HSIO_SERDES6G_ANA_CFG_IB_CFG_VBAC(x)            ((x) << 7)
75 #define         HSIO_SERDES6G_ANA_CFG_IB_CFG_RT(x)              ((x) << 9)
76 #define         HSIO_SERDES6G_ANA_CFG_IB_CFG_RF(x)              ((x) << 14)
77 #define HSIO_SERDES6G_ANA_CFG_IB_CFG1   0x6c
78 #define         HSIO_SERDES6G_ANA_CFG_IB_CFG1_RST               BIT(0)
79 #define         HSIO_SERDES6G_ANA_CFG_IB_CFG1_ENA_OFFSDC        BIT(2)
80 #define         HSIO_SERDES6G_ANA_CFG_IB_CFG1_ENA_OFFSAC        BIT(3)
81 #define         HSIO_SERDES6G_ANA_CFG_IB_CFG1_ANEG_MODE BIT(6)
82 #define         HSIO_SERDES6G_ANA_CFG_IB_CFG1_CHF               BIT(7)
83 #define         HSIO_SERDES6G_ANA_CFG_IB_CFG1_C(x)              ((x) << 8)
84 #define HSIO_SERDES6G_ANA_CFG_OB_CFG    0x70
85 #define         HSIO_SERDES6G_ANA_CFG_OB_CFG_SR(x)              ((x) << 4)
86 #define         HSIO_SERDES6G_ANA_CFG_OB_CFG_SR_H               BIT(8)
87 #define         HSIO_SERDES6G_ANA_CFG_OB_CFG_POST0(x)           ((x) << 23)
88 #define         HSIO_SERDES6G_ANA_CFG_OB_CFG_POL                BIT(29)
89 #define         HSIO_SERDES6G_ANA_CFG_OB_CFG_ENA1V_MODE BIT(30)
90 #define HSIO_SERDES6G_ANA_CFG_OB_CFG1   0x74
91 #define         HSIO_SERDES6G_ANA_CFG_OB_CFG1_LEV(x)            (x)
92 #define         HSIO_SERDES6G_ANA_CFG_OB_CFG1_ENA_CAS(x)        ((x) << 6)
93 #define HSIO_SERDES6G_ANA_CFG_COMMON_CFG 0x7c
94 #define         HSIO_SERDES6G_ANA_CFG_COMMON_CFG_IF_MODE(x)     (x)
95 #define         HSIO_SERDES6G_ANA_CFG_COMMON_CFG_ENA_LANE       BIT(18)
96 #define         HSIO_SERDES6G_ANA_CFG_COMMON_CFG_SYS_RST        BIT(31)
97 #define HSIO_SERDES6G_ANA_CFG_PLL_CFG   0x80
98 #define         HSIO_SERDES6G_ANA_CFG_PLL_CFG_FSM_ENA           BIT(7)
99 #define         HSIO_SERDES6G_ANA_CFG_PLL_CFG_FSM_CTRL_DATA(x)  ((x) << 8)
100 #define HSIO_SERDES6G_ANA_CFG_SER_CFG   0x84
101 #define HSIO_SERDES6G_DIG_CFG_MISC_CFG  0x88
102 #define         HSIO_SERDES6G_DIG_CFG_MISC_CFG_LANE_RST         BIT(0)
103 #define HSIO_MCB_SERDES6G_CFG           0xac
104 #define         HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT               BIT(31)
105 #define         HSIO_MCB_SERDES6G_CFG_ADDR(x)                   (x)
106
107 #define DEV_GMII_PORT_MODE_CLK          0x0
108 #define         DEV_GMII_PORT_MODE_CLK_PHY_RST  BIT(0)
109 #define DEV_GMII_MAC_CFG_MAC_ENA        0xc
110 #define         DEV_GMII_MAC_CFG_MAC_ENA_RX_ENA         BIT(4)
111 #define         DEV_GMII_MAC_CFG_MAC_ENA_TX_ENA         BIT(0)
112
113 #define DEV_PORT_MODE_CLK               0x4
114 #define         DEV_PORT_MODE_CLK_PHY_RST               BIT(2)
115 #define         DEV_PORT_MODE_CLK_LINK_SPEED_1000       1
116 #define DEV_MAC_CFG_MAC_ENA             0x10
117 #define         DEV_MAC_CFG_MAC_ENA_RX_ENA              BIT(4)
118 #define         DEV_MAC_CFG_MAC_ENA_TX_ENA              BIT(0)
119 #define DEV_MAC_CFG_MAC_IFG             0x24
120 #define         DEV_MAC_CFG_MAC_IFG_TX_IFG(x)           ((x) << 8)
121 #define         DEV_MAC_CFG_MAC_IFG_RX_IFG2(x)          ((x) << 4)
122 #define         DEV_MAC_CFG_MAC_IFG_RX_IFG1(x)          (x)
123 #define DEV_PCS1G_CFG_PCS1G_CFG         0x40
124 #define         DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA         BIT(0)
125 #define DEV_PCS1G_CFG_PCS1G_MODE        0x44
126 #define DEV_PCS1G_CFG_PCS1G_SD          0x48
127 #define DEV_PCS1G_CFG_PCS1G_ANEG        0x4c
128 #define         DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(x) ((x) << 16)
129
130 #define IFH_INJ_BYPASS          BIT(31)
131 #define IFH_TAG_TYPE_C          0
132 #define MAC_VID                 1
133 #define CPU_PORT                26
134 #define INTERNAL_PORT_MSK       0xFFFFFF
135 #define IFH_LEN                 2
136 #define ETH_ALEN                6
137 #define PGID_BROADCAST          28
138 #define PGID_UNICAST            29
139 #define PGID_SRC                80
140
141 static const char * const regs_names[] = {
142         "port0", "port1", "port2", "port3", "port4", "port5", "port6", "port7",
143         "port8", "port9", "port10", "port11", "port12", "port13", "port14",
144         "port15", "port16", "port17", "port18", "port19", "port20", "port21",
145         "port22", "port23",
146         "sys", "ana", "rew", "gcb", "qs", "hsio",
147 };
148
149 #define REGS_NAMES_COUNT ARRAY_SIZE(regs_names) + 1
150 #define MAX_PORT 24
151
152 enum luton_ctrl_regs {
153         SYS = MAX_PORT,
154         ANA,
155         REW,
156         GCB,
157         QS,
158         HSIO
159 };
160
161 #define MIN_INT_PORT    0
162 #define PORT10          10
163 #define PORT11          11
164 #define MAX_INT_PORT    12
165 #define MIN_EXT_PORT    MAX_INT_PORT
166 #define MAX_EXT_PORT    MAX_PORT
167
168 #define LUTON_MIIM_BUS_COUNT 2
169
170 struct luton_phy_port_t {
171         size_t phy_addr;
172         struct mii_dev *bus;
173         u8 serdes_index;
174         u8 phy_mode;
175 };
176
177 struct luton_private {
178         void __iomem *regs[REGS_NAMES_COUNT];
179         struct mii_dev *bus[LUTON_MIIM_BUS_COUNT];
180         struct luton_phy_port_t ports[MAX_PORT];
181 };
182
183 static const unsigned long luton_regs_qs[] = {
184         [MSCC_QS_XTR_RD] = 0x18,
185         [MSCC_QS_XTR_FLUSH] = 0x28,
186         [MSCC_QS_XTR_DATA_PRESENT] = 0x2c,
187         [MSCC_QS_INJ_WR] = 0x3c,
188         [MSCC_QS_INJ_CTRL] = 0x44,
189 };
190
191 static const unsigned long luton_regs_ana_table[] = {
192         [MSCC_ANA_TABLES_MACHDATA] = 0x11b0,
193         [MSCC_ANA_TABLES_MACLDATA] = 0x11b4,
194         [MSCC_ANA_TABLES_MACACCESS] = 0x11b8,
195 };
196
197 static struct mscc_miim_dev miim[LUTON_MIIM_BUS_COUNT];
198 static int miim_count = -1;
199
200 static void luton_stop(struct udevice *dev)
201 {
202         struct luton_private *priv = dev_get_priv(dev);
203
204         /*
205          * Switch core only reset affects VCORE-III bus and MIPS frequency
206          * and thereby also the DDR SDRAM controller. The workaround is to
207          * not to redirect any trafic to the CPU after the data transfer.
208          */
209         writel(GENMASK(9, 2), priv->regs[SYS] + SYS_SCH_CPU);
210 }
211
212 static void luton_cpu_capture_setup(struct luton_private *priv)
213 {
214         int i;
215
216         /* map the 8 CPU extraction queues to CPU port 26 */
217         writel(0x0, priv->regs[SYS] + SYS_SCH_CPU);
218
219         for (i = 0; i <= 1; i++) {
220                 /*
221                  * One to one mapping from CPU Queue number to Group extraction
222                  * number
223                  */
224                 writel(QS_XTR_MAP_ENA | (QS_XTR_MAP_GRP * i),
225                        priv->regs[QS] + QS_XTR_MAP(i));
226
227                 /* Enable IFH insertion/parsing on CPU ports */
228                 setbits_le32(priv->regs[REW] + REW_PORT_CFG(CPU_PORT + i),
229                              REW_PORT_CFG_IFH_INSERT_ENA);
230
231                 /* Enable IFH parsing on CPU port 0 and 1 */
232                 setbits_le32(priv->regs[SYS] + SYS_PORT_MODE(CPU_PORT + i),
233                              SYS_PORT_MODE_INCL_INJ_HDR);
234         }
235
236         /* Make VLAN aware for CPU traffic */
237         writel(ANA_PORT_VLAN_CFG_AWARE_ENA |
238                ANA_PORT_VLAN_CFG_POP_CNT(1) |
239                MAC_VID,
240                priv->regs[ANA] + ANA_PORT_VLAN_CFG(CPU_PORT));
241
242         /* Disable learning (only RECV_ENA must be set) */
243         writel(ANA_PORT_PORT_CFG_RECV_ENA,
244                priv->regs[ANA] + ANA_PORT_PORT_CFG(CPU_PORT));
245
246         /* Enable switching to/from cpu port */
247         setbits_le32(priv->regs[SYS] + SYS_SWITCH_PORT_MODE(CPU_PORT),
248                      SYS_SWITCH_PORT_MODE_PORT_ENA);
249
250         setbits_le32(priv->regs[SYS] + SYS_EGR_NO_SHARING, BIT(CPU_PORT));
251 }
252
253 static void luton_gmii_port_init(struct luton_private *priv, int port)
254 {
255         void __iomem *regs = priv->regs[port];
256
257         writel(0, regs + DEV_GMII_PORT_MODE_CLK);
258
259         /* Enable MAC RX and TX */
260         writel(DEV_GMII_MAC_CFG_MAC_ENA_RX_ENA |
261                DEV_GMII_MAC_CFG_MAC_ENA_TX_ENA,
262                regs + DEV_GMII_MAC_CFG_MAC_ENA);
263
264         /* Make VLAN aware for CPU traffic */
265         writel(ANA_PORT_VLAN_CFG_AWARE_ENA |
266                ANA_PORT_VLAN_CFG_POP_CNT(1) |
267                MAC_VID,
268                priv->regs[ANA] + ANA_PORT_VLAN_CFG(port));
269
270         /* Enable switching to/from port */
271         setbits_le32(priv->regs[SYS] + SYS_SWITCH_PORT_MODE(port),
272                      SYS_SWITCH_PORT_MODE_PORT_ENA);
273 }
274
275 static void luton_port_init(struct luton_private *priv, int port)
276 {
277         void __iomem *regs = priv->regs[port];
278
279         writel(0, regs + DEV_PORT_MODE_CLK);
280
281         /* Enable MAC RX and TX */
282         writel(DEV_MAC_CFG_MAC_ENA_RX_ENA |
283                DEV_MAC_CFG_MAC_ENA_TX_ENA,
284                regs + DEV_MAC_CFG_MAC_ENA);
285
286         /* Make VLAN aware for CPU traffic */
287         writel(ANA_PORT_VLAN_CFG_AWARE_ENA |
288                ANA_PORT_VLAN_CFG_POP_CNT(1) |
289                MAC_VID,
290                priv->regs[ANA] + ANA_PORT_VLAN_CFG(port));
291
292         /* Enable switching to/from port */
293         setbits_le32(priv->regs[SYS] + SYS_SWITCH_PORT_MODE(port),
294                      SYS_SWITCH_PORT_MODE_PORT_ENA);
295 }
296
297 static void luton_ext_port_init(struct luton_private *priv, int port)
298 {
299         void __iomem *regs = priv->regs[port];
300
301         /* Enable PCS */
302         writel(DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA,
303                regs + DEV_PCS1G_CFG_PCS1G_CFG);
304
305         /* Disable Signal Detect */
306         writel(0, regs + DEV_PCS1G_CFG_PCS1G_SD);
307
308         /* Enable MAC RX and TX */
309         writel(DEV_MAC_CFG_MAC_ENA_RX_ENA |
310                DEV_MAC_CFG_MAC_ENA_TX_ENA,
311                regs + DEV_MAC_CFG_MAC_ENA);
312
313         /* Clear sgmii_mode_ena */
314         writel(0, regs + DEV_PCS1G_CFG_PCS1G_MODE);
315
316         /*
317          * Clear sw_resolve_ena(bit 0) and set adv_ability to
318          * something meaningful just in case
319          */
320         writel(DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(0x20),
321                regs + DEV_PCS1G_CFG_PCS1G_ANEG);
322
323         /* Set MAC IFG Gaps */
324         writel(DEV_MAC_CFG_MAC_IFG_TX_IFG(7) |
325                DEV_MAC_CFG_MAC_IFG_RX_IFG1(1) |
326                DEV_MAC_CFG_MAC_IFG_RX_IFG2(5),
327                regs + DEV_MAC_CFG_MAC_IFG);
328
329         /* Set link speed and release all resets */
330         writel(DEV_PORT_MODE_CLK_LINK_SPEED_1000,
331                regs + DEV_PORT_MODE_CLK);
332
333         /* Make VLAN aware for CPU traffic */
334         writel(ANA_PORT_VLAN_CFG_AWARE_ENA |
335                ANA_PORT_VLAN_CFG_POP_CNT(1) |
336                MAC_VID,
337                priv->regs[ANA] + ANA_PORT_VLAN_CFG(port));
338
339         /* Enable switching to/from port */
340         setbits_le32(priv->regs[SYS] + SYS_SWITCH_PORT_MODE(port),
341                      SYS_SWITCH_PORT_MODE_PORT_ENA);
342 }
343
344 static void serdes6g_write(void __iomem *base, u32 addr)
345 {
346         u32 data;
347
348         writel(HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT |
349                HSIO_MCB_SERDES6G_CFG_ADDR(addr),
350                base + HSIO_MCB_SERDES6G_CFG);
351
352         do {
353                 data = readl(base + HSIO_MCB_SERDES6G_CFG);
354         } while (data & HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT);
355 }
356
357 static void serdes6g_setup(void __iomem *base, uint32_t addr,
358                            phy_interface_t interface)
359 {
360         writel(HSIO_RCOMP_CFG_CFG0_MODE_SEL(0x3) |
361                HSIO_RCOMP_CFG_CFG0_RUN_CAL,
362                base + HSIO_RCOMP_CFG_CFG0);
363
364         while (readl(base + HSIO_RCOMP_STATUS) &
365                HSIO_RCOMP_STATUS_BUSY)
366                 ;
367
368         writel(HSIO_SERDES6G_ANA_CFG_OB_CFG_SR(0xb) |
369                HSIO_SERDES6G_ANA_CFG_OB_CFG_SR_H |
370                HSIO_SERDES6G_ANA_CFG_OB_CFG_POST0(0x10) |
371                HSIO_SERDES6G_ANA_CFG_OB_CFG_POL |
372                HSIO_SERDES6G_ANA_CFG_OB_CFG_ENA1V_MODE,
373                base + HSIO_SERDES6G_ANA_CFG_OB_CFG);
374         writel(HSIO_SERDES6G_ANA_CFG_OB_CFG1_LEV(0x18) |
375                HSIO_SERDES6G_ANA_CFG_OB_CFG1_ENA_CAS(0x1),
376                base + HSIO_SERDES6G_ANA_CFG_OB_CFG1);
377         writel(HSIO_SERDES6G_ANA_CFG_IB_CFG_RESISTOR_CTRL(0xc) |
378                HSIO_SERDES6G_ANA_CFG_IB_CFG_VBCOM(0x4) |
379                HSIO_SERDES6G_ANA_CFG_IB_CFG_VBAC(0x5) |
380                HSIO_SERDES6G_ANA_CFG_IB_CFG_RT(0xf) |
381                HSIO_SERDES6G_ANA_CFG_IB_CFG_RF(0x4),
382                base + HSIO_SERDES6G_ANA_CFG_IB_CFG);
383         writel(HSIO_SERDES6G_ANA_CFG_IB_CFG1_RST |
384                HSIO_SERDES6G_ANA_CFG_IB_CFG1_ENA_OFFSDC |
385                HSIO_SERDES6G_ANA_CFG_IB_CFG1_ENA_OFFSAC |
386                HSIO_SERDES6G_ANA_CFG_IB_CFG1_ANEG_MODE |
387                HSIO_SERDES6G_ANA_CFG_IB_CFG1_CHF |
388                HSIO_SERDES6G_ANA_CFG_IB_CFG1_C(0x4),
389                base + HSIO_SERDES6G_ANA_CFG_IB_CFG1);
390         writel(HSIO_SERDES6G_ANA_CFG_DES_CFG_BW_ANA(0x5) |
391                HSIO_SERDES6G_ANA_CFG_DES_CFG_BW_HYST(0x5) |
392                HSIO_SERDES6G_ANA_CFG_DES_CFG_MBTR_CTRL(0x2) |
393                HSIO_SERDES6G_ANA_CFG_DES_CFG_PHS_CTRL(0x6),
394                base + HSIO_SERDES6G_ANA_CFG_DES_CFG);
395         writel(HSIO_SERDES6G_ANA_CFG_PLL_CFG_FSM_ENA |
396                HSIO_SERDES6G_ANA_CFG_PLL_CFG_FSM_CTRL_DATA(0x78),
397                base + HSIO_SERDES6G_ANA_CFG_PLL_CFG);
398         writel(HSIO_SERDES6G_ANA_CFG_COMMON_CFG_IF_MODE(0x30) |
399                HSIO_SERDES6G_ANA_CFG_COMMON_CFG_ENA_LANE,
400                base + HSIO_SERDES6G_ANA_CFG_COMMON_CFG);
401         /*
402          * There are 4 serdes6g, configure all except serdes6g0, therefore
403          * the address is b1110
404          */
405         serdes6g_write(base, addr);
406
407         writel(readl(base + HSIO_SERDES6G_ANA_CFG_COMMON_CFG) |
408                HSIO_SERDES6G_ANA_CFG_COMMON_CFG_SYS_RST,
409                base + HSIO_SERDES6G_ANA_CFG_COMMON_CFG);
410         serdes6g_write(base, addr);
411
412         clrbits_le32(base + HSIO_SERDES6G_ANA_CFG_IB_CFG1,
413                      HSIO_SERDES6G_ANA_CFG_IB_CFG1_RST);
414         writel(HSIO_SERDES6G_DIG_CFG_MISC_CFG_LANE_RST,
415                base + HSIO_SERDES6G_DIG_CFG_MISC_CFG);
416         serdes6g_write(base, addr);
417 }
418
419 static void serdes_setup(struct luton_private *priv)
420 {
421         size_t mask;
422         int i = 0;
423
424         for (i = 0; i < MAX_PORT; ++i) {
425                 if (!priv->ports[i].bus || priv->ports[i].serdes_index == 0xff)
426                         continue;
427
428                 mask = BIT(priv->ports[i].serdes_index);
429                 serdes6g_setup(priv->regs[HSIO], mask, priv->ports[i].phy_mode);
430         }
431 }
432
433 static int luton_switch_init(struct luton_private *priv)
434 {
435         setbits_le32(priv->regs[HSIO] + HSIO_PLL5G_CFG_PLL5G_CFG2, BIT(1));
436         clrbits_le32(priv->regs[HSIO] + HSIO_PLL5G_CFG_PLL5G_CFG2, BIT(1));
437
438         /* Reset switch & memories */
439         writel(SYS_SYSTEM_RST_MEM_ENA | SYS_SYSTEM_RST_MEM_INIT,
440                priv->regs[SYS] + SYS_SYSTEM_RST_CFG);
441
442         /* Wait to complete */
443         if (wait_for_bit_le32(priv->regs[SYS] + SYS_SYSTEM_RST_CFG,
444                               SYS_SYSTEM_RST_MEM_INIT, false, 2000, false)) {
445                 printf("Timeout in memory reset\n");
446         }
447
448         /* Enable switch core */
449         setbits_le32(priv->regs[SYS] + SYS_SYSTEM_RST_CFG,
450                      SYS_SYSTEM_RST_CORE_ENA);
451
452         /* Setup the Serdes macros */
453         serdes_setup(priv);
454
455         return 0;
456 }
457
458 static int luton_initialize(struct luton_private *priv)
459 {
460         int ret, i;
461
462         /* Initialize switch memories, enable core */
463         ret = luton_switch_init(priv);
464         if (ret)
465                 return ret;
466
467         /*
468          * Disable port-to-port by switching
469          * Put front ports in "port isolation modes" - i.e. they can't send
470          * to other ports - via the PGID sorce masks.
471          */
472         for (i = 0; i < MAX_PORT; i++)
473                 writel(0, priv->regs[ANA] + ANA_PGID(PGID_SRC + i));
474
475         /* Flush queues */
476         mscc_flush(priv->regs[QS], luton_regs_qs);
477
478         /* Setup frame ageing - "2 sec" - The unit is 4ns on Luton*/
479         writel(2000000000 / 4,
480                priv->regs[SYS] + SYS_FRM_AGING);
481
482         for (i = 0; i < MAX_PORT; i++) {
483                 if (i < PORT10)
484                         luton_gmii_port_init(priv, i);
485                 else
486                         if (i == PORT10 || i == PORT11)
487                                 luton_port_init(priv, i);
488                         else
489                                 luton_ext_port_init(priv, i);
490         }
491
492         luton_cpu_capture_setup(priv);
493
494         return 0;
495 }
496
497 static int luton_write_hwaddr(struct udevice *dev)
498 {
499         struct luton_private *priv = dev_get_priv(dev);
500         struct eth_pdata *pdata = dev_get_platdata(dev);
501
502         mscc_mac_table_add(priv->regs[ANA], luton_regs_ana_table,
503                            pdata->enetaddr, PGID_UNICAST);
504
505         writel(BIT(CPU_PORT), priv->regs[ANA] + ANA_PGID(PGID_UNICAST));
506
507         return 0;
508 }
509
510 static int luton_start(struct udevice *dev)
511 {
512         struct luton_private *priv = dev_get_priv(dev);
513         struct eth_pdata *pdata = dev_get_platdata(dev);
514         const unsigned char mac[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff,
515                                               0xff };
516         int ret;
517
518         ret = luton_initialize(priv);
519         if (ret)
520                 return ret;
521
522         /* Set MAC address tables entries for CPU redirection */
523         mscc_mac_table_add(priv->regs[ANA], luton_regs_ana_table,
524                            mac, PGID_BROADCAST);
525
526         writel(BIT(CPU_PORT) | INTERNAL_PORT_MSK,
527                priv->regs[ANA] + ANA_PGID(PGID_BROADCAST));
528
529         mscc_mac_table_add(priv->regs[ANA], luton_regs_ana_table,
530                            pdata->enetaddr, PGID_UNICAST);
531
532         writel(BIT(CPU_PORT), priv->regs[ANA] + ANA_PGID(PGID_UNICAST));
533
534         return 0;
535 }
536
537 static int luton_send(struct udevice *dev, void *packet, int length)
538 {
539         struct luton_private *priv = dev_get_priv(dev);
540         u32 ifh[IFH_LEN];
541         int port = BIT(0);      /* use port 0 */
542         u32 *buf = packet;
543
544         ifh[0] = IFH_INJ_BYPASS | port;
545         ifh[1] = (IFH_TAG_TYPE_C << 16);
546
547         return mscc_send(priv->regs[QS], luton_regs_qs,
548                          ifh, IFH_LEN, buf, length);
549 }
550
551 static int luton_recv(struct udevice *dev, int flags, uchar **packetp)
552 {
553         struct luton_private *priv = dev_get_priv(dev);
554         u32 *rxbuf = (u32 *)net_rx_packets[0];
555         int byte_cnt = 0;
556
557         byte_cnt = mscc_recv(priv->regs[QS], luton_regs_qs, rxbuf, IFH_LEN,
558                              true);
559
560         *packetp = net_rx_packets[0];
561
562         return byte_cnt;
563 }
564
565 static struct mii_dev *get_mdiobus(phys_addr_t base, unsigned long size)
566 {
567         int i = 0;
568
569         for (i = 0; i < LUTON_MIIM_BUS_COUNT; ++i)
570                 if (miim[i].miim_base == base && miim[i].miim_size == size)
571                         return miim[i].bus;
572
573         return NULL;
574 }
575
576 static void add_port_entry(struct luton_private *priv, size_t index,
577                            size_t phy_addr, struct mii_dev *bus,
578                            u8 serdes_index, u8 phy_mode)
579 {
580         priv->ports[index].phy_addr = phy_addr;
581         priv->ports[index].bus = bus;
582         priv->ports[index].serdes_index = serdes_index;
583         priv->ports[index].phy_mode = phy_mode;
584 }
585
586 static int luton_probe(struct udevice *dev)
587 {
588         struct luton_private *priv = dev_get_priv(dev);
589         int i, ret;
590         struct resource res;
591         fdt32_t faddr;
592         phys_addr_t addr_base;
593         unsigned long addr_size;
594         ofnode eth_node, node, mdio_node;
595         size_t phy_addr;
596         struct mii_dev *bus;
597         struct ofnode_phandle_args phandle;
598         struct phy_device *phy;
599
600         if (!priv)
601                 return -EINVAL;
602
603         /* Get registers and map them to the private structure */
604         for (i = 0; i < ARRAY_SIZE(regs_names); i++) {
605                 priv->regs[i] = dev_remap_addr_name(dev, regs_names[i]);
606                 if (!priv->regs[i]) {
607                         debug
608                             ("Error can't get regs base addresses for %s\n",
609                              regs_names[i]);
610                         return -ENOMEM;
611                 }
612         }
613
614         /* Release reset in the CU-PHY */
615         writel(0, priv->regs[GCB] + GCB_DEVCPU_RST_SOFT_CHIP_RST);
616
617         /* Ports with ext phy don't need to reset clk */
618         for (i = 0; i < MAX_INT_PORT; i++) {
619                 if (i < PORT10)
620                         clrbits_le32(priv->regs[i] + DEV_GMII_PORT_MODE_CLK,
621                                      DEV_GMII_PORT_MODE_CLK_PHY_RST);
622                 else
623                         clrbits_le32(priv->regs[i] + DEV_PORT_MODE_CLK,
624                                      DEV_PORT_MODE_CLK_PHY_RST);
625         }
626
627         /* Wait for internal PHY to be ready */
628         if (wait_for_bit_le32(priv->regs[GCB] + GCB_MISC_STAT,
629                               GCB_MISC_STAT_PHY_READY, true, 500, false))
630                 return -EACCES;
631
632
633         /* Initialize miim buses */
634         memset(&miim, 0x0, sizeof(miim) * LUTON_MIIM_BUS_COUNT);
635
636         /* iterate all the ports and find out on which bus they are */
637         i = 0;
638         eth_node = dev_read_first_subnode(dev);
639         for (node = ofnode_first_subnode(eth_node);
640              ofnode_valid(node);
641              node = ofnode_next_subnode(node)) {
642                 if (ofnode_read_resource(node, 0, &res))
643                         return -ENOMEM;
644                 i = res.start;
645
646                 ret = ofnode_parse_phandle_with_args(node, "phy-handle", NULL,
647                                                      0, 0, &phandle);
648                 if (ret)
649                         continue;
650
651                 /* Get phy address on mdio bus */
652                 if (ofnode_read_resource(phandle.node, 0, &res))
653                         return -ENOMEM;
654                 phy_addr = res.start;
655
656                 /* Get mdio node */
657                 mdio_node = ofnode_get_parent(phandle.node);
658
659                 if (ofnode_read_resource(mdio_node, 0, &res))
660                         return -ENOMEM;
661                 faddr = cpu_to_fdt32(res.start);
662
663                 addr_base = ofnode_translate_address(mdio_node, &faddr);
664                 addr_size = res.end - res.start;
665
666                 /* If the bus is new then create a new bus */
667                 if (!get_mdiobus(addr_base, addr_size))
668                         priv->bus[miim_count] =
669                                 mscc_mdiobus_init(miim, &miim_count, addr_base,
670                                                   addr_size);
671
672                 /* Connect mdio bus with the port */
673                 bus = get_mdiobus(addr_base, addr_size);
674
675                 /* Get serdes info */
676                 ret = ofnode_parse_phandle_with_args(node, "phys", NULL,
677                                                      3, 0, &phandle);
678                 if (ret)
679                         add_port_entry(priv, i, phy_addr, bus, 0xff, 0xff);
680                 else
681                         add_port_entry(priv, i, phy_addr, bus, phandle.args[1],
682                                        phandle.args[2]);
683         }
684
685         for (i = 0; i < MAX_PORT; i++) {
686                 if (!priv->ports[i].bus)
687                         continue;
688
689                 phy = phy_connect(priv->ports[i].bus,
690                                   priv->ports[i].phy_addr, dev,
691                                   PHY_INTERFACE_MODE_NONE);
692                 if (phy && i >= MAX_INT_PORT)
693                         board_phy_config(phy);
694         }
695
696         /*
697          * coma_mode is need on only one phy, because all the other phys
698          * will be affected.
699          */
700         mscc_miim_write(priv->ports[0].bus, 0, 0, 31, 0x10);
701         mscc_miim_write(priv->ports[0].bus, 0, 0, 14, 0x800);
702         mscc_miim_write(priv->ports[0].bus, 0, 0, 31, 0);
703
704         return 0;
705 }
706
707 static int luton_remove(struct udevice *dev)
708 {
709         struct luton_private *priv = dev_get_priv(dev);
710         int i;
711
712         for (i = 0; i < LUTON_MIIM_BUS_COUNT; i++) {
713                 mdio_unregister(priv->bus[i]);
714                 mdio_free(priv->bus[i]);
715         }
716
717         return 0;
718 }
719
720 static const struct eth_ops luton_ops = {
721         .start        = luton_start,
722         .stop         = luton_stop,
723         .send         = luton_send,
724         .recv         = luton_recv,
725         .write_hwaddr = luton_write_hwaddr,
726 };
727
728 static const struct udevice_id mscc_luton_ids[] = {
729         {.compatible = "mscc,vsc7527-switch", },
730         { /* Sentinel */ }
731 };
732
733 U_BOOT_DRIVER(luton) = {
734         .name     = "luton-switch",
735         .id       = UCLASS_ETH,
736         .of_match = mscc_luton_ids,
737         .probe    = luton_probe,
738         .remove   = luton_remove,
739         .ops      = &luton_ops,
740         .priv_auto_alloc_size = sizeof(struct luton_private),
741         .platdata_auto_alloc_size = sizeof(struct eth_pdata),
742 };