1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <dm/device_compat.h>
19#include <linux/delay.h>
20#include <net/dsa.h>
21#include <asm/io.h>
22#include <miiphy.h>
23#include <pci.h>
24
25
26#include "../fsl_enetc.h"
27
28#define PCI_DEVICE_ID_FELIX_ETHSW 0xEEF0
29
30
31#define FELIX_PORT_COUNT 5
32
33#define FELIX_FP_PORT_MASK 0xf
34
35
36#define FELIX_SYS 0x010000
37#define FELIX_ES0 0x040000
38#define FELIX_IS1 0x050000
39#define FELIX_IS2 0x060000
40#define FELIX_GMII(port) (0x100000 + (port) * 0x10000)
41#define FELIX_QSYS 0x200000
42
43#define FELIX_SYS_SYSTEM (FELIX_SYS + 0x00000E00)
44#define FELIX_SYS_SYSTEM_EN BIT(0)
45#define FELIX_SYS_RAM_CTRL (FELIX_SYS + 0x00000F24)
46#define FELIX_SYS_RAM_CTRL_INIT BIT(1)
47#define FELIX_SYS_SYSTEM_PORT_MODE(a) (FELIX_SYS_SYSTEM + 0xC + (a) * 4)
48#define FELIX_SYS_SYSTEM_PORT_MODE_CPU 0x0000001e
49
50#define FELIX_ES0_TCAM_CTRL (FELIX_ES0 + 0x000003C0)
51#define FELIX_ES0_TCAM_CTRL_EN BIT(0)
52#define FELIX_IS1_TCAM_CTRL (FELIX_IS1 + 0x000003C0)
53#define FELIX_IS1_TCAM_CTRL_EN BIT(0)
54#define FELIX_IS2_TCAM_CTRL (FELIX_IS2 + 0x000003C0)
55#define FELIX_IS2_TCAM_CTRL_EN BIT(0)
56
57#define FELIX_GMII_CLOCK_CFG(port) (FELIX_GMII(port) + 0x00000000)
58#define FELIX_GMII_CLOCK_CFG_LINK_1G 1
59#define FELIX_GMII_CLOCK_CFG_LINK_100M 2
60#define FELIX_GMII_CLOCK_CFG_LINK_10M 3
61#define FELIX_GMII_MAC_ENA_CFG(port) (FELIX_GMII(port) + 0x0000001C)
62#define FELIX_GMII_MAX_ENA_CFG_TX BIT(0)
63#define FELIX_GMII_MAX_ENA_CFG_RX BIT(4)
64#define FELIX_GMII_MAC_IFG_CFG(port) (FELIX_GMII(port) + 0x0000001C + 0x14)
65#define FELIX_GMII_MAC_IFG_CFG_DEF 0x515
66
67#define FELIX_QSYS_SYSTEM (FELIX_QSYS + 0x0000F460)
68#define FELIX_QSYS_SYSTEM_SW_PORT_MODE(a) \
69 (FELIX_QSYS_SYSTEM + 0x20 + (a) * 4)
70#define FELIX_QSYS_SYSTEM_SW_PORT_ENA BIT(14)
71#define FELIX_QSYS_SYSTEM_SW_PORT_LOSSY BIT(9)
72#define FELIX_QSYS_SYSTEM_SW_PORT_SCH(a) (((a) & 0x3800) << 11)
73#define FELIX_QSYS_SYSTEM_EXT_CPU_CFG (FELIX_QSYS_SYSTEM + 0x80)
74#define FELIX_QSYS_SYSTEM_EXT_CPU_PORT(a) (((a) & 0xf) << 8 | 0xff)
75
76
77#define FELIX_PM_IMDIO_BASE 0x8030
78
79
80#define FELIX_SERDES_BASE 0x1ea0000L
81#define FELIX_SERDES_LNATECR0(lane) (FELIX_SERDES_BASE + 0x818 + \
82 (lane) * 0x40)
83#define FELIX_SERDES_LNATECR0_ADPT_EQ 0x00003000
84#define FELIX_SERDES_SGMIICR1(lane) (FELIX_SERDES_BASE + 0x1804 + \
85 (lane) * 0x10)
86#define FELIX_SERDES_SGMIICR1_SGPCS BIT(11)
87#define FELIX_SERDES_SGMIICR1_MDEV(a) (((a) & 0x1f) << 27)
88
89#define FELIX_PCS_CTRL 0
90#define FELIX_PCS_CTRL_RST BIT(15)
91
92
93
94
95
96
97#define FELIX_DSA_TAG_LEN sizeof(struct felix_dsa_tag)
98#define FELIX_DSA_TAG_MAGIC 0x0a008088
99#define FELIX_DSA_TAG_INJ_PORT 7
100#define FELIX_DSA_TAG_INJ_PORT_SET(a) (0x1 << ((a) & FELIX_FP_PORT_MASK))
101#define FELIX_DSA_TAG_EXT_PORT 10
102#define FELIX_DSA_TAG_EXT_PORT_GET(a) ((a) >> 3)
103
104struct felix_dsa_tag {
105 uchar d_mac[6];
106 uchar s_mac[6];
107 u32 magic;
108 uchar meta[16];
109};
110
111struct felix_priv {
112 void *regs_base;
113 void *imdio_base;
114 struct mii_dev imdio;
115};
116
117
118static int felix_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
119{
120 struct enetc_mdio_priv priv;
121
122 priv.regs_base = bus->priv;
123 return enetc_mdio_read_priv(&priv, addr, devad, reg);
124}
125
126static int felix_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
127 u16 val)
128{
129 struct enetc_mdio_priv priv;
130
131 priv.regs_base = bus->priv;
132 return enetc_mdio_write_priv(&priv, addr, devad, reg, val);
133}
134
135
136static void felix_init_sgmii(struct mii_dev *imdio, int pidx, bool an)
137{
138 u16 reg;
139
140
141 out_le32(FELIX_SERDES_SGMIICR1(pidx), FELIX_SERDES_SGMIICR1_SGPCS |
142 FELIX_SERDES_SGMIICR1_MDEV(pidx));
143
144
145
146
147
148
149
150 reg = ENETC_PCS_IF_MODE_SGMII;
151 reg |= an ? ENETC_PCS_IF_MODE_SGMII_AN : ENETC_PCS_IF_MODE_SPEED_1G;
152 felix_mdio_write(imdio, pidx, MDIO_DEVAD_NONE,
153 ENETC_PCS_IF_MODE, reg);
154
155
156 felix_mdio_write(imdio, pidx, MDIO_DEVAD_NONE,
157 ENETC_PCS_DEV_ABILITY, ENETC_PCS_DEV_ABILITY_SGMII);
158
159
160 felix_mdio_write(imdio, pidx, MDIO_DEVAD_NONE,
161 ENETC_PCS_LINK_TIMER1, ENETC_PCS_LINK_TIMER1_VAL);
162 felix_mdio_write(imdio, pidx, MDIO_DEVAD_NONE,
163 ENETC_PCS_LINK_TIMER2, ENETC_PCS_LINK_TIMER2_VAL);
164
165 reg = ENETC_PCS_CR_DEF_VAL;
166 reg |= an ? ENETC_PCS_CR_RESET_AN : ENETC_PCS_CR_RST;
167
168 felix_mdio_write(imdio, pidx, MDIO_DEVAD_NONE,
169 ENETC_PCS_CR, reg);
170}
171
172
173static int felix_init_sxgmii(struct mii_dev *imdio, int pidx)
174{
175 int timeout = 1000;
176
177
178 out_le32(FELIX_SERDES_LNATECR0(1), FELIX_SERDES_LNATECR0_ADPT_EQ);
179
180
181 felix_mdio_write(imdio, pidx, MDIO_MMD_PCS, FELIX_PCS_CTRL,
182 FELIX_PCS_CTRL_RST);
183 while (felix_mdio_read(imdio, pidx, MDIO_MMD_PCS,
184 FELIX_PCS_CTRL) & FELIX_PCS_CTRL_RST &&
185 --timeout) {
186 mdelay(10);
187 }
188 if (felix_mdio_read(imdio, pidx, MDIO_MMD_PCS,
189 FELIX_PCS_CTRL) & FELIX_PCS_CTRL_RST)
190 return -ETIME;
191
192
193 felix_mdio_write(imdio, pidx, ENETC_PCS_DEVAD_REPL,
194 ENETC_PCS_DEV_ABILITY, ENETC_PCS_DEV_ABILITY_SXGMII);
195
196
197 felix_mdio_write(imdio, pidx, ENETC_PCS_DEVAD_REPL, ENETC_PCS_CR,
198 ENETC_PCS_CR_RST | ENETC_PCS_CR_RESET_AN);
199 felix_mdio_write(imdio, pidx, ENETC_PCS_DEVAD_REPL,
200 ENETC_PCS_REPL_LINK_TIMER_1,
201 ENETC_PCS_REPL_LINK_TIMER_1_DEF);
202 felix_mdio_write(imdio, pidx, ENETC_PCS_DEVAD_REPL,
203 ENETC_PCS_REPL_LINK_TIMER_2,
204 ENETC_PCS_REPL_LINK_TIMER_2_DEF);
205
206 return 0;
207}
208
209
210static void felix_start_pcs(struct udevice *dev, int port,
211 struct phy_device *phy, struct mii_dev *imdio)
212{
213 bool autoneg = true;
214
215 if (phy->phy_id == PHY_FIXED_ID ||
216 phy->interface == PHY_INTERFACE_MODE_SGMII_2500)
217 autoneg = false;
218
219 switch (phy->interface) {
220 case PHY_INTERFACE_MODE_SGMII:
221 case PHY_INTERFACE_MODE_SGMII_2500:
222 case PHY_INTERFACE_MODE_QSGMII:
223 felix_init_sgmii(imdio, port, autoneg);
224 break;
225 case PHY_INTERFACE_MODE_XGMII:
226 case PHY_INTERFACE_MODE_XFI:
227 case PHY_INTERFACE_MODE_USXGMII:
228 if (felix_init_sxgmii(imdio, port))
229 dev_err(dev, "PCS reset timeout on port %d\n", port);
230 break;
231 default:
232 break;
233 }
234}
235
236void felix_init(struct udevice *dev)
237{
238 struct dsa_pdata *pdata = dev_get_uclass_plat(dev);
239 struct felix_priv *priv = dev_get_priv(dev);
240 void *base = priv->regs_base;
241 int timeout = 100;
242
243
244 out_le32(base + FELIX_SYS_RAM_CTRL, FELIX_SYS_RAM_CTRL_INIT);
245 while (in_le32(base + FELIX_SYS_RAM_CTRL) & FELIX_SYS_RAM_CTRL_INIT &&
246 --timeout)
247 udelay(10);
248 if (in_le32(base + FELIX_SYS_RAM_CTRL) & FELIX_SYS_RAM_CTRL_INIT)
249 dev_err(dev, "Timeout waiting for switch memories\n");
250
251
252 out_le32(base + FELIX_SYS_SYSTEM, FELIX_SYS_SYSTEM_EN);
253 out_le32(base + FELIX_ES0_TCAM_CTRL, FELIX_ES0_TCAM_CTRL_EN);
254 out_le32(base + FELIX_IS1_TCAM_CTRL, FELIX_IS1_TCAM_CTRL_EN);
255 out_le32(base + FELIX_IS2_TCAM_CTRL, FELIX_IS2_TCAM_CTRL_EN);
256 udelay(20);
257
258 priv->imdio.read = felix_mdio_read;
259 priv->imdio.write = felix_mdio_write;
260 priv->imdio.priv = priv->imdio_base + FELIX_PM_IMDIO_BASE;
261 strncpy(priv->imdio.name, dev->name, MDIO_NAME_LEN);
262
263
264 out_le32(base + FELIX_QSYS_SYSTEM_EXT_CPU_CFG,
265 FELIX_QSYS_SYSTEM_EXT_CPU_PORT(pdata->cpu_port));
266 out_le32(base + FELIX_SYS_SYSTEM_PORT_MODE(pdata->cpu_port),
267 FELIX_SYS_SYSTEM_PORT_MODE_CPU);
268}
269
270
271
272
273
274
275
276static int felix_probe(struct udevice *dev)
277{
278 struct felix_priv *priv = dev_get_priv(dev);
279
280 if (ofnode_valid(dev_ofnode(dev)) &&
281 !ofnode_is_available(dev_ofnode(dev))) {
282 dev_dbg(dev, "switch disabled\n");
283 return -ENODEV;
284 }
285
286 priv->imdio_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0);
287 if (!priv->imdio_base) {
288 dev_err(dev, "failed to map BAR0\n");
289 return -EINVAL;
290 }
291
292 priv->regs_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_4, 0);
293 if (!priv->regs_base) {
294 dev_err(dev, "failed to map BAR4\n");
295 return -EINVAL;
296 }
297
298
299 if (!miiphy_get_dev_by_name(dev->name)) {
300 struct mii_dev *mii_bus;
301
302 mii_bus = mdio_alloc();
303 mii_bus->read = felix_mdio_read;
304 mii_bus->write = felix_mdio_write;
305 mii_bus->priv = priv->imdio_base + FELIX_PM_IMDIO_BASE;
306 strncpy(mii_bus->name, dev->name, MDIO_NAME_LEN);
307 mdio_register(mii_bus);
308 }
309
310 dm_pci_clrset_config16(dev, PCI_COMMAND, 0, PCI_COMMAND_MEMORY);
311
312 dsa_set_tagging(dev, FELIX_DSA_TAG_LEN, 0);
313
314
315 felix_init(dev);
316
317 return 0;
318}
319
320static int felix_port_enable(struct udevice *dev, int port,
321 struct phy_device *phy)
322{
323 int supported = PHY_GBIT_FEATURES | SUPPORTED_2500baseX_Full;
324 struct felix_priv *priv = dev_get_priv(dev);
325 void *base = priv->regs_base;
326
327
328 out_le32(base + FELIX_GMII_CLOCK_CFG(port),
329 FELIX_GMII_CLOCK_CFG_LINK_1G);
330
331 out_le32(base + FELIX_GMII_MAC_IFG_CFG(port),
332 FELIX_GMII_MAC_IFG_CFG_DEF);
333
334 out_le32(base + FELIX_GMII_MAC_ENA_CFG(port),
335 FELIX_GMII_MAX_ENA_CFG_TX | FELIX_GMII_MAX_ENA_CFG_RX);
336
337 out_le32(base + FELIX_QSYS_SYSTEM_SW_PORT_MODE(port),
338 FELIX_QSYS_SYSTEM_SW_PORT_ENA |
339 FELIX_QSYS_SYSTEM_SW_PORT_LOSSY |
340 FELIX_QSYS_SYSTEM_SW_PORT_SCH(1));
341
342 felix_start_pcs(dev, port, phy, &priv->imdio);
343
344 phy->supported &= supported;
345 phy->advertising &= supported;
346 phy_config(phy);
347
348 phy_startup(phy);
349
350 return 0;
351}
352
353static void felix_port_disable(struct udevice *dev, int pidx,
354 struct phy_device *phy)
355{
356 struct felix_priv *priv = dev_get_priv(dev);
357 void *base = priv->regs_base;
358
359 out_le32(base + FELIX_GMII_MAC_ENA_CFG(pidx), 0);
360
361 out_le32(base + FELIX_QSYS_SYSTEM_SW_PORT_MODE(pidx),
362 FELIX_QSYS_SYSTEM_SW_PORT_LOSSY |
363 FELIX_QSYS_SYSTEM_SW_PORT_SCH(1));
364
365
366
367
368
369
370}
371
372static int felix_xmit(struct udevice *dev, int pidx, void *packet, int length)
373{
374 struct felix_dsa_tag *tag = packet;
375
376 tag->magic = FELIX_DSA_TAG_MAGIC;
377 tag->meta[FELIX_DSA_TAG_INJ_PORT] = FELIX_DSA_TAG_INJ_PORT_SET(pidx);
378
379 return 0;
380}
381
382static int felix_rcv(struct udevice *dev, int *pidx, void *packet, int length)
383{
384 struct felix_dsa_tag *tag = packet;
385
386 if (tag->magic != FELIX_DSA_TAG_MAGIC)
387 return -EINVAL;
388
389 *pidx = FELIX_DSA_TAG_EXT_PORT_GET(tag->meta[FELIX_DSA_TAG_EXT_PORT]);
390
391 return 0;
392}
393
394static const struct dsa_ops felix_dsa_ops = {
395 .port_enable = felix_port_enable,
396 .port_disable = felix_port_disable,
397 .xmit = felix_xmit,
398 .rcv = felix_rcv,
399};
400
401U_BOOT_DRIVER(felix_ethsw) = {
402 .name = "felix-switch",
403 .id = UCLASS_DSA,
404 .probe = felix_probe,
405 .ops = &felix_dsa_ops,
406 .priv_auto = sizeof(struct felix_priv),
407};
408
409static struct pci_device_id felix_ethsw_ids[] = {
410 { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, PCI_DEVICE_ID_FELIX_ETHSW) },
411 {}
412};
413
414U_BOOT_PCI_DEVICE(felix_ethsw, felix_ethsw_ids);
415