Loading...
Note: File does not exist in v3.15.
1// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
2/*
3 * NXP NETC Blocks Control Driver
4 *
5 * Copyright 2024 NXP
6 *
7 * This driver is used for pre-initialization of NETC, such as PCS and MII
8 * protocols, LDID, warm reset, etc. Therefore, all NETC device drivers can
9 * only be probed after the netc-blk-crtl driver has completed initialization.
10 * In addition, when the system enters suspend mode, IERB, PRB, and NETCMIX
11 * will be powered off, except for WOL. Therefore, when the system resumes,
12 * these blocks need to be reinitialized.
13 */
14
15#include <linux/bits.h>
16#include <linux/clk.h>
17#include <linux/debugfs.h>
18#include <linux/delay.h>
19#include <linux/fsl/netc_global.h>
20#include <linux/module.h>
21#include <linux/of.h>
22#include <linux/of_device.h>
23#include <linux/of_net.h>
24#include <linux/of_platform.h>
25#include <linux/phy.h>
26#include <linux/platform_device.h>
27#include <linux/seq_file.h>
28
29/* NETCMIX registers */
30#define IMX95_CFG_LINK_IO_VAR 0x0
31#define IO_VAR_16FF_16G_SERDES 0x1
32#define IO_VAR(port, var) (((var) & 0xf) << ((port) << 2))
33
34#define IMX95_CFG_LINK_MII_PROT 0x4
35#define CFG_LINK_MII_PORT_0 GENMASK(3, 0)
36#define CFG_LINK_MII_PORT_1 GENMASK(7, 4)
37#define MII_PROT_MII 0x0
38#define MII_PROT_RMII 0x1
39#define MII_PROT_RGMII 0x2
40#define MII_PROT_SERIAL 0x3
41#define MII_PROT(port, prot) (((prot) & 0xf) << ((port) << 2))
42
43#define IMX95_CFG_LINK_PCS_PROT(a) (0x8 + (a) * 4)
44#define PCS_PROT_1G_SGMII BIT(0)
45#define PCS_PROT_2500M_SGMII BIT(1)
46#define PCS_PROT_XFI BIT(3)
47#define PCS_PROT_SFI BIT(4)
48#define PCS_PROT_10G_SXGMII BIT(6)
49
50/* NETC privileged register block register */
51#define PRB_NETCRR 0x100
52#define NETCRR_SR BIT(0)
53#define NETCRR_LOCK BIT(1)
54
55#define PRB_NETCSR 0x104
56#define NETCSR_ERROR BIT(0)
57#define NETCSR_STATE BIT(1)
58
59/* NETC integrated endpoint register block register */
60#define IERB_EMDIOFAUXR 0x344
61#define IERB_T0FAUXR 0x444
62#define IERB_EFAUXR(a) (0x3044 + 0x100 * (a))
63#define IERB_VFAUXR(a) (0x4004 + 0x40 * (a))
64#define FAUXR_LDID GENMASK(3, 0)
65
66/* Platform information */
67#define IMX95_ENETC0_BUS_DEVFN 0x0
68#define IMX95_ENETC1_BUS_DEVFN 0x40
69#define IMX95_ENETC2_BUS_DEVFN 0x80
70
71/* Flags for different platforms */
72#define NETC_HAS_NETCMIX BIT(0)
73
74struct netc_devinfo {
75 u32 flags;
76 int (*netcmix_init)(struct platform_device *pdev);
77 int (*ierb_init)(struct platform_device *pdev);
78};
79
80struct netc_blk_ctrl {
81 void __iomem *prb;
82 void __iomem *ierb;
83 void __iomem *netcmix;
84
85 const struct netc_devinfo *devinfo;
86 struct platform_device *pdev;
87 struct dentry *debugfs_root;
88};
89
90static void netc_reg_write(void __iomem *base, u32 offset, u32 val)
91{
92 netc_write(base + offset, val);
93}
94
95static u32 netc_reg_read(void __iomem *base, u32 offset)
96{
97 return netc_read(base + offset);
98}
99
100static int netc_of_pci_get_bus_devfn(struct device_node *np)
101{
102 u32 reg[5];
103 int error;
104
105 error = of_property_read_u32_array(np, "reg", reg, ARRAY_SIZE(reg));
106 if (error)
107 return error;
108
109 return (reg[0] >> 8) & 0xffff;
110}
111
112static int netc_get_link_mii_protocol(phy_interface_t interface)
113{
114 switch (interface) {
115 case PHY_INTERFACE_MODE_MII:
116 return MII_PROT_MII;
117 case PHY_INTERFACE_MODE_RMII:
118 return MII_PROT_RMII;
119 case PHY_INTERFACE_MODE_RGMII:
120 case PHY_INTERFACE_MODE_RGMII_ID:
121 case PHY_INTERFACE_MODE_RGMII_RXID:
122 case PHY_INTERFACE_MODE_RGMII_TXID:
123 return MII_PROT_RGMII;
124 case PHY_INTERFACE_MODE_SGMII:
125 case PHY_INTERFACE_MODE_2500BASEX:
126 case PHY_INTERFACE_MODE_10GBASER:
127 case PHY_INTERFACE_MODE_XGMII:
128 case PHY_INTERFACE_MODE_USXGMII:
129 return MII_PROT_SERIAL;
130 default:
131 return -EINVAL;
132 }
133}
134
135static int imx95_netcmix_init(struct platform_device *pdev)
136{
137 struct netc_blk_ctrl *priv = platform_get_drvdata(pdev);
138 struct device_node *np = pdev->dev.of_node;
139 phy_interface_t interface;
140 int bus_devfn, mii_proto;
141 u32 val;
142 int err;
143
144 /* Default setting of MII protocol */
145 val = MII_PROT(0, MII_PROT_RGMII) | MII_PROT(1, MII_PROT_RGMII) |
146 MII_PROT(2, MII_PROT_SERIAL);
147
148 /* Update the link MII protocol through parsing phy-mode */
149 for_each_available_child_of_node_scoped(np, child) {
150 for_each_available_child_of_node_scoped(child, gchild) {
151 if (!of_device_is_compatible(gchild, "pci1131,e101"))
152 continue;
153
154 bus_devfn = netc_of_pci_get_bus_devfn(gchild);
155 if (bus_devfn < 0)
156 return -EINVAL;
157
158 if (bus_devfn == IMX95_ENETC2_BUS_DEVFN)
159 continue;
160
161 err = of_get_phy_mode(gchild, &interface);
162 if (err)
163 continue;
164
165 mii_proto = netc_get_link_mii_protocol(interface);
166 if (mii_proto < 0)
167 return -EINVAL;
168
169 switch (bus_devfn) {
170 case IMX95_ENETC0_BUS_DEVFN:
171 val = u32_replace_bits(val, mii_proto,
172 CFG_LINK_MII_PORT_0);
173 break;
174 case IMX95_ENETC1_BUS_DEVFN:
175 val = u32_replace_bits(val, mii_proto,
176 CFG_LINK_MII_PORT_1);
177 break;
178 default:
179 return -EINVAL;
180 }
181 }
182 }
183
184 /* Configure Link I/O variant */
185 netc_reg_write(priv->netcmix, IMX95_CFG_LINK_IO_VAR,
186 IO_VAR(2, IO_VAR_16FF_16G_SERDES));
187 /* Configure Link 2 PCS protocol */
188 netc_reg_write(priv->netcmix, IMX95_CFG_LINK_PCS_PROT(2),
189 PCS_PROT_10G_SXGMII);
190 netc_reg_write(priv->netcmix, IMX95_CFG_LINK_MII_PROT, val);
191
192 return 0;
193}
194
195static bool netc_ierb_is_locked(struct netc_blk_ctrl *priv)
196{
197 return !!(netc_reg_read(priv->prb, PRB_NETCRR) & NETCRR_LOCK);
198}
199
200static int netc_lock_ierb(struct netc_blk_ctrl *priv)
201{
202 u32 val;
203
204 netc_reg_write(priv->prb, PRB_NETCRR, NETCRR_LOCK);
205
206 return read_poll_timeout(netc_reg_read, val, !(val & NETCSR_STATE),
207 100, 2000, false, priv->prb, PRB_NETCSR);
208}
209
210static int netc_unlock_ierb_with_warm_reset(struct netc_blk_ctrl *priv)
211{
212 u32 val;
213
214 netc_reg_write(priv->prb, PRB_NETCRR, 0);
215
216 return read_poll_timeout(netc_reg_read, val, !(val & NETCRR_LOCK),
217 1000, 100000, true, priv->prb, PRB_NETCRR);
218}
219
220static int imx95_ierb_init(struct platform_device *pdev)
221{
222 struct netc_blk_ctrl *priv = platform_get_drvdata(pdev);
223
224 /* EMDIO : No MSI-X intterupt */
225 netc_reg_write(priv->ierb, IERB_EMDIOFAUXR, 0);
226 /* ENETC0 PF */
227 netc_reg_write(priv->ierb, IERB_EFAUXR(0), 0);
228 /* ENETC0 VF0 */
229 netc_reg_write(priv->ierb, IERB_VFAUXR(0), 1);
230 /* ENETC0 VF1 */
231 netc_reg_write(priv->ierb, IERB_VFAUXR(1), 2);
232 /* ENETC1 PF */
233 netc_reg_write(priv->ierb, IERB_EFAUXR(1), 3);
234 /* ENETC1 VF0 */
235 netc_reg_write(priv->ierb, IERB_VFAUXR(2), 5);
236 /* ENETC1 VF1 */
237 netc_reg_write(priv->ierb, IERB_VFAUXR(3), 6);
238 /* ENETC2 PF */
239 netc_reg_write(priv->ierb, IERB_EFAUXR(2), 4);
240 /* ENETC2 VF0 */
241 netc_reg_write(priv->ierb, IERB_VFAUXR(4), 5);
242 /* ENETC2 VF1 */
243 netc_reg_write(priv->ierb, IERB_VFAUXR(5), 6);
244 /* NETC TIMER */
245 netc_reg_write(priv->ierb, IERB_T0FAUXR, 7);
246
247 return 0;
248}
249
250static int netc_ierb_init(struct platform_device *pdev)
251{
252 struct netc_blk_ctrl *priv = platform_get_drvdata(pdev);
253 const struct netc_devinfo *devinfo = priv->devinfo;
254 int err;
255
256 if (netc_ierb_is_locked(priv)) {
257 err = netc_unlock_ierb_with_warm_reset(priv);
258 if (err) {
259 dev_err(&pdev->dev, "Unlock IERB failed.\n");
260 return err;
261 }
262 }
263
264 if (devinfo->ierb_init) {
265 err = devinfo->ierb_init(pdev);
266 if (err)
267 return err;
268 }
269
270 err = netc_lock_ierb(priv);
271 if (err) {
272 dev_err(&pdev->dev, "Lock IERB failed.\n");
273 return err;
274 }
275
276 return 0;
277}
278
279#if IS_ENABLED(CONFIG_DEBUG_FS)
280static int netc_prb_show(struct seq_file *s, void *data)
281{
282 struct netc_blk_ctrl *priv = s->private;
283 u32 val;
284
285 val = netc_reg_read(priv->prb, PRB_NETCRR);
286 seq_printf(s, "[PRB NETCRR] Lock:%d SR:%d\n",
287 (val & NETCRR_LOCK) ? 1 : 0,
288 (val & NETCRR_SR) ? 1 : 0);
289
290 val = netc_reg_read(priv->prb, PRB_NETCSR);
291 seq_printf(s, "[PRB NETCSR] State:%d Error:%d\n",
292 (val & NETCSR_STATE) ? 1 : 0,
293 (val & NETCSR_ERROR) ? 1 : 0);
294
295 return 0;
296}
297DEFINE_SHOW_ATTRIBUTE(netc_prb);
298
299static void netc_blk_ctrl_create_debugfs(struct netc_blk_ctrl *priv)
300{
301 struct dentry *root;
302
303 root = debugfs_create_dir("netc_blk_ctrl", NULL);
304 if (IS_ERR(root))
305 return;
306
307 priv->debugfs_root = root;
308
309 debugfs_create_file("prb", 0444, root, priv, &netc_prb_fops);
310}
311
312static void netc_blk_ctrl_remove_debugfs(struct netc_blk_ctrl *priv)
313{
314 debugfs_remove_recursive(priv->debugfs_root);
315 priv->debugfs_root = NULL;
316}
317
318#else
319
320static void netc_blk_ctrl_create_debugfs(struct netc_blk_ctrl *priv)
321{
322}
323
324static void netc_blk_ctrl_remove_debugfs(struct netc_blk_ctrl *priv)
325{
326}
327#endif
328
329static int netc_prb_check_error(struct netc_blk_ctrl *priv)
330{
331 if (netc_reg_read(priv->prb, PRB_NETCSR) & NETCSR_ERROR)
332 return -1;
333
334 return 0;
335}
336
337static const struct netc_devinfo imx95_devinfo = {
338 .flags = NETC_HAS_NETCMIX,
339 .netcmix_init = imx95_netcmix_init,
340 .ierb_init = imx95_ierb_init,
341};
342
343static const struct of_device_id netc_blk_ctrl_match[] = {
344 { .compatible = "nxp,imx95-netc-blk-ctrl", .data = &imx95_devinfo },
345 {},
346};
347MODULE_DEVICE_TABLE(of, netc_blk_ctrl_match);
348
349static int netc_blk_ctrl_probe(struct platform_device *pdev)
350{
351 struct device_node *node = pdev->dev.of_node;
352 const struct netc_devinfo *devinfo;
353 struct device *dev = &pdev->dev;
354 const struct of_device_id *id;
355 struct netc_blk_ctrl *priv;
356 struct clk *ipg_clk;
357 void __iomem *regs;
358 int err;
359
360 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
361 if (!priv)
362 return -ENOMEM;
363
364 priv->pdev = pdev;
365 ipg_clk = devm_clk_get_optional_enabled(dev, "ipg");
366 if (IS_ERR(ipg_clk))
367 return dev_err_probe(dev, PTR_ERR(ipg_clk),
368 "Set ipg clock failed\n");
369
370 id = of_match_device(netc_blk_ctrl_match, dev);
371 if (!id)
372 return dev_err_probe(dev, -EINVAL, "Cannot match device\n");
373
374 devinfo = (struct netc_devinfo *)id->data;
375 if (!devinfo)
376 return dev_err_probe(dev, -EINVAL, "No device information\n");
377
378 priv->devinfo = devinfo;
379 regs = devm_platform_ioremap_resource_byname(pdev, "ierb");
380 if (IS_ERR(regs))
381 return dev_err_probe(dev, PTR_ERR(regs),
382 "Missing IERB resource\n");
383
384 priv->ierb = regs;
385 regs = devm_platform_ioremap_resource_byname(pdev, "prb");
386 if (IS_ERR(regs))
387 return dev_err_probe(dev, PTR_ERR(regs),
388 "Missing PRB resource\n");
389
390 priv->prb = regs;
391 if (devinfo->flags & NETC_HAS_NETCMIX) {
392 regs = devm_platform_ioremap_resource_byname(pdev, "netcmix");
393 if (IS_ERR(regs))
394 return dev_err_probe(dev, PTR_ERR(regs),
395 "Missing NETCMIX resource\n");
396 priv->netcmix = regs;
397 }
398
399 platform_set_drvdata(pdev, priv);
400 if (devinfo->netcmix_init) {
401 err = devinfo->netcmix_init(pdev);
402 if (err)
403 return dev_err_probe(dev, err,
404 "Initializing NETCMIX failed\n");
405 }
406
407 err = netc_ierb_init(pdev);
408 if (err)
409 return dev_err_probe(dev, err, "Initializing IERB failed\n");
410
411 if (netc_prb_check_error(priv) < 0)
412 dev_warn(dev, "The current IERB configuration is invalid\n");
413
414 netc_blk_ctrl_create_debugfs(priv);
415
416 err = of_platform_populate(node, NULL, NULL, dev);
417 if (err) {
418 netc_blk_ctrl_remove_debugfs(priv);
419 return dev_err_probe(dev, err, "of_platform_populate failed\n");
420 }
421
422 return 0;
423}
424
425static void netc_blk_ctrl_remove(struct platform_device *pdev)
426{
427 struct netc_blk_ctrl *priv = platform_get_drvdata(pdev);
428
429 of_platform_depopulate(&pdev->dev);
430 netc_blk_ctrl_remove_debugfs(priv);
431}
432
433static struct platform_driver netc_blk_ctrl_driver = {
434 .driver = {
435 .name = "nxp-netc-blk-ctrl",
436 .of_match_table = netc_blk_ctrl_match,
437 },
438 .probe = netc_blk_ctrl_probe,
439 .remove = netc_blk_ctrl_remove,
440};
441
442module_platform_driver(netc_blk_ctrl_driver);
443
444MODULE_DESCRIPTION("NXP NETC Blocks Control Driver");
445MODULE_LICENSE("Dual BSD/GPL");