blob: 2df8dde55fb9755444cf87273bbc382aa4f76105 [file] [log] [blame]
Alex Marginean4ea74fd2021-01-25 14:23:55 +02001// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
2/*
3 * Felix (VSC9959) Ethernet switch driver
Vladimir Oltean5041e422021-09-17 14:27:13 +03004 * Copyright 2018-2021 NXP
Alex Marginean4ea74fd2021-01-25 14:23:55 +02005 */
6
7/*
8 * This driver is used for the Ethernet switch integrated into NXP LS1028A.
9 * Felix switch is derived from Microsemi Ocelot but there are several NXP
10 * adaptations that makes the two U-Boot drivers largely incompatible.
11 *
12 * Felix on LS1028A has 4 front panel ports and two internal ports, connected
13 * to ENETC interfaces. We're using one of the ENETC interfaces to push traffic
14 * into the switch. Injection/extraction headers are used to identify
15 * egress/ingress ports in the switch for Tx/Rx.
16 */
17
18#include <dm/device_compat.h>
Vladimir Oltean1ecc6892021-09-29 18:04:40 +030019#include <dm/of_extra.h>
Alex Marginean4ea74fd2021-01-25 14:23:55 +020020#include <linux/delay.h>
21#include <net/dsa.h>
22#include <asm/io.h>
23#include <miiphy.h>
24#include <pci.h>
25
26/* defines especially around PCS are reused from enetc */
27#include "../fsl_enetc.h"
28
29#define PCI_DEVICE_ID_FELIX_ETHSW 0xEEF0
30
31/* Felix has in fact 6 ports, but we don't use the last internal one */
32#define FELIX_PORT_COUNT 5
33/* Front panel port mask */
34#define FELIX_FP_PORT_MASK 0xf
35
36/* Register map for BAR4 */
37#define FELIX_SYS 0x010000
38#define FELIX_ES0 0x040000
39#define FELIX_IS1 0x050000
40#define FELIX_IS2 0x060000
41#define FELIX_GMII(port) (0x100000 + (port) * 0x10000)
42#define FELIX_QSYS 0x200000
43
44#define FELIX_SYS_SYSTEM (FELIX_SYS + 0x00000E00)
45#define FELIX_SYS_SYSTEM_EN BIT(0)
46#define FELIX_SYS_RAM_CTRL (FELIX_SYS + 0x00000F24)
47#define FELIX_SYS_RAM_CTRL_INIT BIT(1)
48#define FELIX_SYS_SYSTEM_PORT_MODE(a) (FELIX_SYS_SYSTEM + 0xC + (a) * 4)
49#define FELIX_SYS_SYSTEM_PORT_MODE_CPU 0x0000001e
50
51#define FELIX_ES0_TCAM_CTRL (FELIX_ES0 + 0x000003C0)
52#define FELIX_ES0_TCAM_CTRL_EN BIT(0)
53#define FELIX_IS1_TCAM_CTRL (FELIX_IS1 + 0x000003C0)
54#define FELIX_IS1_TCAM_CTRL_EN BIT(0)
55#define FELIX_IS2_TCAM_CTRL (FELIX_IS2 + 0x000003C0)
56#define FELIX_IS2_TCAM_CTRL_EN BIT(0)
57
58#define FELIX_GMII_CLOCK_CFG(port) (FELIX_GMII(port) + 0x00000000)
59#define FELIX_GMII_CLOCK_CFG_LINK_1G 1
60#define FELIX_GMII_CLOCK_CFG_LINK_100M 2
61#define FELIX_GMII_CLOCK_CFG_LINK_10M 3
62#define FELIX_GMII_MAC_ENA_CFG(port) (FELIX_GMII(port) + 0x0000001C)
63#define FELIX_GMII_MAX_ENA_CFG_TX BIT(0)
64#define FELIX_GMII_MAX_ENA_CFG_RX BIT(4)
65#define FELIX_GMII_MAC_IFG_CFG(port) (FELIX_GMII(port) + 0x0000001C + 0x14)
66#define FELIX_GMII_MAC_IFG_CFG_DEF 0x515
67
68#define FELIX_QSYS_SYSTEM (FELIX_QSYS + 0x0000F460)
69#define FELIX_QSYS_SYSTEM_SW_PORT_MODE(a) \
70 (FELIX_QSYS_SYSTEM + 0x20 + (a) * 4)
71#define FELIX_QSYS_SYSTEM_SW_PORT_ENA BIT(14)
72#define FELIX_QSYS_SYSTEM_SW_PORT_LOSSY BIT(9)
73#define FELIX_QSYS_SYSTEM_SW_PORT_SCH(a) (((a) & 0x3800) << 11)
74#define FELIX_QSYS_SYSTEM_EXT_CPU_CFG (FELIX_QSYS_SYSTEM + 0x80)
75#define FELIX_QSYS_SYSTEM_EXT_CPU_PORT(a) (((a) & 0xf) << 8 | 0xff)
76
77/* internal MDIO in BAR0 */
78#define FELIX_PM_IMDIO_BASE 0x8030
79
80/* Serdes block on LS1028A */
81#define FELIX_SERDES_BASE 0x1ea0000L
82#define FELIX_SERDES_LNATECR0(lane) (FELIX_SERDES_BASE + 0x818 + \
83 (lane) * 0x40)
84#define FELIX_SERDES_LNATECR0_ADPT_EQ 0x00003000
85#define FELIX_SERDES_SGMIICR1(lane) (FELIX_SERDES_BASE + 0x1804 + \
86 (lane) * 0x10)
87#define FELIX_SERDES_SGMIICR1_SGPCS BIT(11)
88#define FELIX_SERDES_SGMIICR1_MDEV(a) (((a) & 0x1f) << 27)
89
90#define FELIX_PCS_CTRL 0
91#define FELIX_PCS_CTRL_RST BIT(15)
92
93/*
94 * The long prefix format used here contains two dummy MAC addresses, a magic
95 * value in place of a VLAN tag followed by the extraction/injection header and
96 * the original L2 frame. Out of all this we only use the port ID.
97 */
98#define FELIX_DSA_TAG_LEN sizeof(struct felix_dsa_tag)
99#define FELIX_DSA_TAG_MAGIC 0x0a008088
100#define FELIX_DSA_TAG_INJ_PORT 7
101#define FELIX_DSA_TAG_INJ_PORT_SET(a) (0x1 << ((a) & FELIX_FP_PORT_MASK))
102#define FELIX_DSA_TAG_EXT_PORT 10
103#define FELIX_DSA_TAG_EXT_PORT_GET(a) ((a) >> 3)
104
105struct felix_dsa_tag {
106 uchar d_mac[6];
107 uchar s_mac[6];
108 u32 magic;
109 uchar meta[16];
110};
111
112struct felix_priv {
113 void *regs_base;
114 void *imdio_base;
115 struct mii_dev imdio;
116};
117
118/* MDIO wrappers, we're using these to drive internal MDIO to get to serdes */
119static int felix_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
120{
121 struct enetc_mdio_priv priv;
122
123 priv.regs_base = bus->priv;
124 return enetc_mdio_read_priv(&priv, addr, devad, reg);
125}
126
127static int felix_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
128 u16 val)
129{
130 struct enetc_mdio_priv priv;
131
132 priv.regs_base = bus->priv;
133 return enetc_mdio_write_priv(&priv, addr, devad, reg, val);
134}
135
136/* set up serdes for SGMII */
137static void felix_init_sgmii(struct mii_dev *imdio, int pidx, bool an)
138{
139 u16 reg;
140
141 /* set up PCS lane address */
142 out_le32(FELIX_SERDES_SGMIICR1(pidx), FELIX_SERDES_SGMIICR1_SGPCS |
143 FELIX_SERDES_SGMIICR1_MDEV(pidx));
144
145 /*
146 * Set to SGMII mode, for 1Gbps enable AN, for 2.5Gbps set fixed speed.
147 * Although fixed speed is 1Gbps, we could be running at 2.5Gbps based
148 * on PLL configuration. Setting 1G for 2.5G here is counter intuitive
149 * but intentional.
150 */
151 reg = ENETC_PCS_IF_MODE_SGMII;
152 reg |= an ? ENETC_PCS_IF_MODE_SGMII_AN : ENETC_PCS_IF_MODE_SPEED_1G;
153 felix_mdio_write(imdio, pidx, MDIO_DEVAD_NONE,
154 ENETC_PCS_IF_MODE, reg);
155
156 /* Dev ability - SGMII */
157 felix_mdio_write(imdio, pidx, MDIO_DEVAD_NONE,
158 ENETC_PCS_DEV_ABILITY, ENETC_PCS_DEV_ABILITY_SGMII);
159
160 /* Adjust link timer for SGMII */
161 felix_mdio_write(imdio, pidx, MDIO_DEVAD_NONE,
162 ENETC_PCS_LINK_TIMER1, ENETC_PCS_LINK_TIMER1_VAL);
163 felix_mdio_write(imdio, pidx, MDIO_DEVAD_NONE,
164 ENETC_PCS_LINK_TIMER2, ENETC_PCS_LINK_TIMER2_VAL);
165
166 reg = ENETC_PCS_CR_DEF_VAL;
167 reg |= an ? ENETC_PCS_CR_RESET_AN : ENETC_PCS_CR_RST;
168 /* restart PCS AN */
169 felix_mdio_write(imdio, pidx, MDIO_DEVAD_NONE,
170 ENETC_PCS_CR, reg);
171}
172
173/* set up MAC and serdes for (Q)SXGMII */
174static int felix_init_sxgmii(struct mii_dev *imdio, int pidx)
175{
176 int timeout = 1000;
177
178 /* set up transit equalization control on serdes lane */
179 out_le32(FELIX_SERDES_LNATECR0(1), FELIX_SERDES_LNATECR0_ADPT_EQ);
180
181 /*reset lane */
182 felix_mdio_write(imdio, pidx, MDIO_MMD_PCS, FELIX_PCS_CTRL,
183 FELIX_PCS_CTRL_RST);
184 while (felix_mdio_read(imdio, pidx, MDIO_MMD_PCS,
185 FELIX_PCS_CTRL) & FELIX_PCS_CTRL_RST &&
186 --timeout) {
187 mdelay(10);
188 }
189 if (felix_mdio_read(imdio, pidx, MDIO_MMD_PCS,
190 FELIX_PCS_CTRL) & FELIX_PCS_CTRL_RST)
191 return -ETIME;
192
193 /* Dev ability - SXGMII */
194 felix_mdio_write(imdio, pidx, ENETC_PCS_DEVAD_REPL,
195 ENETC_PCS_DEV_ABILITY, ENETC_PCS_DEV_ABILITY_SXGMII);
196
197 /* Restart PCS AN */
198 felix_mdio_write(imdio, pidx, ENETC_PCS_DEVAD_REPL, ENETC_PCS_CR,
199 ENETC_PCS_CR_RST | ENETC_PCS_CR_RESET_AN);
200 felix_mdio_write(imdio, pidx, ENETC_PCS_DEVAD_REPL,
201 ENETC_PCS_REPL_LINK_TIMER_1,
202 ENETC_PCS_REPL_LINK_TIMER_1_DEF);
203 felix_mdio_write(imdio, pidx, ENETC_PCS_DEVAD_REPL,
204 ENETC_PCS_REPL_LINK_TIMER_2,
205 ENETC_PCS_REPL_LINK_TIMER_2_DEF);
206
207 return 0;
208}
209
210/* Apply protocol specific configuration to MAC, serdes as needed */
211static void felix_start_pcs(struct udevice *dev, int port,
212 struct phy_device *phy, struct mii_dev *imdio)
213{
Vladimir Oltean1ecc6892021-09-29 18:04:40 +0300214 ofnode node = dsa_port_get_ofnode(dev, port);
215 bool inband_an = ofnode_eth_uses_inband_aneg(node);
Alex Marginean4ea74fd2021-01-25 14:23:55 +0200216
217 switch (phy->interface) {
218 case PHY_INTERFACE_MODE_SGMII:
Vladimir Oltean6caef972021-09-18 15:32:35 +0300219 case PHY_INTERFACE_MODE_2500BASEX:
Alex Marginean4ea74fd2021-01-25 14:23:55 +0200220 case PHY_INTERFACE_MODE_QSGMII:
Vladimir Oltean1ecc6892021-09-29 18:04:40 +0300221 felix_init_sgmii(imdio, port, inband_an);
Alex Marginean4ea74fd2021-01-25 14:23:55 +0200222 break;
Vladimir Oltean6a6e4022021-09-18 15:32:34 +0300223 case PHY_INTERFACE_MODE_10GBASER:
Alex Marginean4ea74fd2021-01-25 14:23:55 +0200224 case PHY_INTERFACE_MODE_USXGMII:
225 if (felix_init_sxgmii(imdio, port))
226 dev_err(dev, "PCS reset timeout on port %d\n", port);
227 break;
228 default:
229 break;
230 }
231}
232
Vladimir Oltean132a8c22021-08-24 15:00:38 +0300233static void felix_init(struct udevice *dev)
Alex Marginean4ea74fd2021-01-25 14:23:55 +0200234{
235 struct dsa_pdata *pdata = dev_get_uclass_plat(dev);
236 struct felix_priv *priv = dev_get_priv(dev);
237 void *base = priv->regs_base;
238 int timeout = 100;
239
240 /* Init core memories */
241 out_le32(base + FELIX_SYS_RAM_CTRL, FELIX_SYS_RAM_CTRL_INIT);
242 while (in_le32(base + FELIX_SYS_RAM_CTRL) & FELIX_SYS_RAM_CTRL_INIT &&
243 --timeout)
244 udelay(10);
245 if (in_le32(base + FELIX_SYS_RAM_CTRL) & FELIX_SYS_RAM_CTRL_INIT)
246 dev_err(dev, "Timeout waiting for switch memories\n");
247
248 /* Start switch core, set up ES0, IS1, IS2 */
249 out_le32(base + FELIX_SYS_SYSTEM, FELIX_SYS_SYSTEM_EN);
250 out_le32(base + FELIX_ES0_TCAM_CTRL, FELIX_ES0_TCAM_CTRL_EN);
251 out_le32(base + FELIX_IS1_TCAM_CTRL, FELIX_IS1_TCAM_CTRL_EN);
252 out_le32(base + FELIX_IS2_TCAM_CTRL, FELIX_IS2_TCAM_CTRL_EN);
253 udelay(20);
254
255 priv->imdio.read = felix_mdio_read;
256 priv->imdio.write = felix_mdio_write;
257 priv->imdio.priv = priv->imdio_base + FELIX_PM_IMDIO_BASE;
Vladimir Oltean1cf22ab2021-09-27 14:21:54 +0300258 strlcpy(priv->imdio.name, dev->name, MDIO_NAME_LEN);
Alex Marginean4ea74fd2021-01-25 14:23:55 +0200259
260 /* set up CPU port */
261 out_le32(base + FELIX_QSYS_SYSTEM_EXT_CPU_CFG,
262 FELIX_QSYS_SYSTEM_EXT_CPU_PORT(pdata->cpu_port));
263 out_le32(base + FELIX_SYS_SYSTEM_PORT_MODE(pdata->cpu_port),
264 FELIX_SYS_SYSTEM_PORT_MODE_CPU);
265}
266
267/*
268 * Probe Felix:
269 * - enable the PCI function
270 * - map BAR 4
271 * - init switch core and port registers
272 */
273static int felix_probe(struct udevice *dev)
274{
275 struct felix_priv *priv = dev_get_priv(dev);
Vladimir Olteane22c9682021-09-27 14:22:02 +0300276 int err;
Alex Marginean4ea74fd2021-01-25 14:23:55 +0200277
278 if (ofnode_valid(dev_ofnode(dev)) &&
279 !ofnode_is_available(dev_ofnode(dev))) {
280 dev_dbg(dev, "switch disabled\n");
281 return -ENODEV;
282 }
283
284 priv->imdio_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0);
285 if (!priv->imdio_base) {
286 dev_err(dev, "failed to map BAR0\n");
287 return -EINVAL;
288 }
289
290 priv->regs_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_4, 0);
291 if (!priv->regs_base) {
292 dev_err(dev, "failed to map BAR4\n");
293 return -EINVAL;
294 }
295
296 /* register internal MDIO for debug */
297 if (!miiphy_get_dev_by_name(dev->name)) {
298 struct mii_dev *mii_bus;
299
300 mii_bus = mdio_alloc();
Vladimir Olteane22c9682021-09-27 14:22:02 +0300301 if (!mii_bus)
302 return -ENOMEM;
303
Alex Marginean4ea74fd2021-01-25 14:23:55 +0200304 mii_bus->read = felix_mdio_read;
305 mii_bus->write = felix_mdio_write;
306 mii_bus->priv = priv->imdio_base + FELIX_PM_IMDIO_BASE;
Vladimir Oltean1cf22ab2021-09-27 14:21:54 +0300307 strlcpy(mii_bus->name, dev->name, MDIO_NAME_LEN);
Vladimir Olteane22c9682021-09-27 14:22:02 +0300308 err = mdio_register(mii_bus);
309 if (err) {
310 mdio_free(mii_bus);
311 return err;
312 }
Alex Marginean4ea74fd2021-01-25 14:23:55 +0200313 }
314
315 dm_pci_clrset_config16(dev, PCI_COMMAND, 0, PCI_COMMAND_MEMORY);
316
317 dsa_set_tagging(dev, FELIX_DSA_TAG_LEN, 0);
318
319 /* set up registers */
320 felix_init(dev);
321
322 return 0;
323}
324
Vladimir Oltean81cec032021-08-24 15:00:42 +0300325static int felix_port_probe(struct udevice *dev, int port,
326 struct phy_device *phy)
327{
328 int supported = PHY_GBIT_FEATURES | SUPPORTED_2500baseX_Full;
329 struct felix_priv *priv = dev_get_priv(dev);
330
331 phy->supported &= supported;
332 phy->advertising &= supported;
333
334 felix_start_pcs(dev, port, phy, &priv->imdio);
335
336 return phy_config(phy);
337}
338
Alex Marginean4ea74fd2021-01-25 14:23:55 +0200339static int felix_port_enable(struct udevice *dev, int port,
340 struct phy_device *phy)
341{
Alex Marginean4ea74fd2021-01-25 14:23:55 +0200342 struct felix_priv *priv = dev_get_priv(dev);
343 void *base = priv->regs_base;
344
345 /* Set up MAC registers */
346 out_le32(base + FELIX_GMII_CLOCK_CFG(port),
347 FELIX_GMII_CLOCK_CFG_LINK_1G);
348
349 out_le32(base + FELIX_GMII_MAC_IFG_CFG(port),
350 FELIX_GMII_MAC_IFG_CFG_DEF);
351
352 out_le32(base + FELIX_GMII_MAC_ENA_CFG(port),
353 FELIX_GMII_MAX_ENA_CFG_TX | FELIX_GMII_MAX_ENA_CFG_RX);
354
355 out_le32(base + FELIX_QSYS_SYSTEM_SW_PORT_MODE(port),
356 FELIX_QSYS_SYSTEM_SW_PORT_ENA |
357 FELIX_QSYS_SYSTEM_SW_PORT_LOSSY |
358 FELIX_QSYS_SYSTEM_SW_PORT_SCH(1));
359
Vladimir Olteane26bcf62021-08-24 15:00:43 +0300360 return phy_startup(phy);
Alex Marginean4ea74fd2021-01-25 14:23:55 +0200361}
362
363static void felix_port_disable(struct udevice *dev, int pidx,
364 struct phy_device *phy)
365{
366 struct felix_priv *priv = dev_get_priv(dev);
367 void *base = priv->regs_base;
368
369 out_le32(base + FELIX_GMII_MAC_ENA_CFG(pidx), 0);
370
371 out_le32(base + FELIX_QSYS_SYSTEM_SW_PORT_MODE(pidx),
372 FELIX_QSYS_SYSTEM_SW_PORT_LOSSY |
373 FELIX_QSYS_SYSTEM_SW_PORT_SCH(1));
374
375 /*
376 * we don't call phy_shutdown here to avoid waiting next time we use
377 * the port, but the downside is that remote side will think we're
378 * actively processing traffic although we are not.
379 */
380}
381
382static int felix_xmit(struct udevice *dev, int pidx, void *packet, int length)
383{
384 struct felix_dsa_tag *tag = packet;
385
386 tag->magic = FELIX_DSA_TAG_MAGIC;
387 tag->meta[FELIX_DSA_TAG_INJ_PORT] = FELIX_DSA_TAG_INJ_PORT_SET(pidx);
388
389 return 0;
390}
391
392static int felix_rcv(struct udevice *dev, int *pidx, void *packet, int length)
393{
394 struct felix_dsa_tag *tag = packet;
395
396 if (tag->magic != FELIX_DSA_TAG_MAGIC)
397 return -EINVAL;
398
399 *pidx = FELIX_DSA_TAG_EXT_PORT_GET(tag->meta[FELIX_DSA_TAG_EXT_PORT]);
400
401 return 0;
402}
403
404static const struct dsa_ops felix_dsa_ops = {
Vladimir Oltean81cec032021-08-24 15:00:42 +0300405 .port_probe = felix_port_probe,
Alex Marginean4ea74fd2021-01-25 14:23:55 +0200406 .port_enable = felix_port_enable,
407 .port_disable = felix_port_disable,
408 .xmit = felix_xmit,
409 .rcv = felix_rcv,
410};
411
412U_BOOT_DRIVER(felix_ethsw) = {
413 .name = "felix-switch",
414 .id = UCLASS_DSA,
415 .probe = felix_probe,
416 .ops = &felix_dsa_ops,
417 .priv_auto = sizeof(struct felix_priv),
418};
419
420static struct pci_device_id felix_ethsw_ids[] = {
421 { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, PCI_DEVICE_ID_FELIX_ETHSW) },
422 {}
423};
424
425U_BOOT_PCI_DEVICE(felix_ethsw, felix_ethsw_ids);