hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
....@@ -1,21 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /* Copyright Altera Corporation (C) 2014. All rights reserved.
2
- *
3
- * This program is free software; you can redistribute it and/or modify
4
- * it under the terms of the GNU General Public License, version 2,
5
- * as published by the Free Software Foundation.
6
- *
7
- * This program is distributed in the hope that it will be useful,
8
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
- * GNU General Public License for more details.
11
- *
12
- * You should have received a copy of the GNU General Public License
13
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
143 *
154 * Adopted from dwmac-sti.c
165 */
176
18
-#include <linux/mfd/syscon.h>
7
+#include <linux/mfd/altera-sysmgr.h>
198 #include <linux/of.h>
209 #include <linux/of_address.h>
2110 #include <linux/of_net.h>
....@@ -29,18 +18,18 @@
2918
3019 #include "altr_tse_pcs.h"
3120
32
-#define SGMII_ADAPTER_CTRL_REG 0x00
33
-#define SGMII_ADAPTER_DISABLE 0x0001
34
-
3521 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0x0
3622 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII 0x1
3723 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII 0x2
3824 #define SYSMGR_EMACGRP_CTRL_PHYSEL_WIDTH 2
3925 #define SYSMGR_EMACGRP_CTRL_PHYSEL_MASK 0x00000003
4026 #define SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK 0x00000010
27
+#define SYSMGR_GEN10_EMACGRP_CTRL_PTP_REF_CLK_MASK 0x00000100
4128
4229 #define SYSMGR_FPGAGRP_MODULE_REG 0x00000028
4330 #define SYSMGR_FPGAGRP_MODULE_EMAC 0x00000004
31
+#define SYSMGR_FPGAINTF_EMAC_REG 0x00000070
32
+#define SYSMGR_FPGAINTF_EMAC_BIT 0x1
4433
4534 #define EMAC_SPLITTER_CTRL_REG 0x0
4635 #define EMAC_SPLITTER_CTRL_SPEED_MASK 0x3
....@@ -48,8 +37,12 @@
4837 #define EMAC_SPLITTER_CTRL_SPEED_100 0x3
4938 #define EMAC_SPLITTER_CTRL_SPEED_1000 0x0
5039
40
+struct socfpga_dwmac;
41
+struct socfpga_dwmac_ops {
42
+ int (*set_phy_mode)(struct socfpga_dwmac *dwmac_priv);
43
+};
44
+
5145 struct socfpga_dwmac {
52
- int interface;
5346 u32 reg_offset;
5447 u32 reg_shift;
5548 struct device *dev;
....@@ -59,20 +52,20 @@
5952 void __iomem *splitter_base;
6053 bool f2h_ptp_ref_clk;
6154 struct tse_pcs pcs;
55
+ const struct socfpga_dwmac_ops *ops;
6256 };
6357
6458 static void socfpga_dwmac_fix_mac_speed(void *priv, unsigned int speed)
6559 {
6660 struct socfpga_dwmac *dwmac = (struct socfpga_dwmac *)priv;
6761 void __iomem *splitter_base = dwmac->splitter_base;
68
- void __iomem *tse_pcs_base = dwmac->pcs.tse_pcs_base;
6962 void __iomem *sgmii_adapter_base = dwmac->pcs.sgmii_adapter_base;
7063 struct device *dev = dwmac->dev;
7164 struct net_device *ndev = dev_get_drvdata(dev);
7265 struct phy_device *phy_dev = ndev->phydev;
7366 u32 val;
7467
75
- if ((tse_pcs_base) && (sgmii_adapter_base))
68
+ if (sgmii_adapter_base)
7669 writew(SGMII_ADAPTER_DISABLE,
7770 sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG);
7871
....@@ -96,8 +89,11 @@
9689 writel(val, splitter_base + EMAC_SPLITTER_CTRL_REG);
9790 }
9891
99
- if (tse_pcs_base && sgmii_adapter_base)
92
+ if (phy_dev && sgmii_adapter_base) {
93
+ writew(SGMII_ADAPTER_ENABLE,
94
+ sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG);
10095 tse_pcs_fix_mac_speed(&dwmac->pcs, phy_dev, speed);
96
+ }
10197 }
10298
10399 static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev)
....@@ -112,9 +108,8 @@
112108 struct resource res_tse_pcs;
113109 struct resource res_sgmii_adapter;
114110
115
- dwmac->interface = of_get_phy_mode(np);
116
-
117
- sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon");
111
+ sys_mgr_base_addr =
112
+ altr_sysmgr_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon");
118113 if (IS_ERR(sys_mgr_base_addr)) {
119114 dev_info(dev, "No sysmgr-syscon node found\n");
120115 return PTR_ERR(sys_mgr_base_addr);
....@@ -232,25 +227,46 @@
232227 return ret;
233228 }
234229
235
-static int socfpga_dwmac_set_phy_mode(struct socfpga_dwmac *dwmac)
230
+static int socfpga_get_plat_phymode(struct socfpga_dwmac *dwmac)
236231 {
237
- struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr;
238
- int phymode = dwmac->interface;
239
- u32 reg_offset = dwmac->reg_offset;
240
- u32 reg_shift = dwmac->reg_shift;
241
- u32 ctrl, val, module;
232
+ struct net_device *ndev = dev_get_drvdata(dwmac->dev);
233
+ struct stmmac_priv *priv = netdev_priv(ndev);
242234
235
+ return priv->plat->interface;
236
+}
237
+
238
+static int socfpga_set_phy_mode_common(int phymode, u32 *val)
239
+{
243240 switch (phymode) {
244241 case PHY_INTERFACE_MODE_RGMII:
245242 case PHY_INTERFACE_MODE_RGMII_ID:
246
- val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
243
+ case PHY_INTERFACE_MODE_RGMII_RXID:
244
+ case PHY_INTERFACE_MODE_RGMII_TXID:
245
+ *val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
247246 break;
248247 case PHY_INTERFACE_MODE_MII:
249248 case PHY_INTERFACE_MODE_GMII:
250249 case PHY_INTERFACE_MODE_SGMII:
251
- val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
250
+ *val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
251
+ break;
252
+ case PHY_INTERFACE_MODE_RMII:
253
+ *val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII;
252254 break;
253255 default:
256
+ return -EINVAL;
257
+ }
258
+ return 0;
259
+}
260
+
261
+static int socfpga_gen5_set_phy_mode(struct socfpga_dwmac *dwmac)
262
+{
263
+ struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr;
264
+ int phymode = socfpga_get_plat_phymode(dwmac);
265
+ u32 reg_offset = dwmac->reg_offset;
266
+ u32 reg_shift = dwmac->reg_shift;
267
+ u32 ctrl, val, module;
268
+
269
+ if (socfpga_set_phy_mode_common(phymode, &val)) {
254270 dev_err(dwmac->dev, "bad phy mode %d\n", phymode);
255271 return -EINVAL;
256272 }
....@@ -304,6 +320,62 @@
304320 return 0;
305321 }
306322
323
+static int socfpga_gen10_set_phy_mode(struct socfpga_dwmac *dwmac)
324
+{
325
+ struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr;
326
+ int phymode = socfpga_get_plat_phymode(dwmac);
327
+ u32 reg_offset = dwmac->reg_offset;
328
+ u32 reg_shift = dwmac->reg_shift;
329
+ u32 ctrl, val, module;
330
+
331
+ if (socfpga_set_phy_mode_common(phymode, &val))
332
+ return -EINVAL;
333
+
334
+ /* Overwrite val to GMII if splitter core is enabled. The phymode here
335
+ * is the actual phy mode on phy hardware, but phy interface from
336
+ * EMAC core is GMII.
337
+ */
338
+ if (dwmac->splitter_base)
339
+ val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
340
+
341
+ /* Assert reset to the enet controller before changing the phy mode */
342
+ reset_control_assert(dwmac->stmmac_ocp_rst);
343
+ reset_control_assert(dwmac->stmmac_rst);
344
+
345
+ regmap_read(sys_mgr_base_addr, reg_offset, &ctrl);
346
+ ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK);
347
+ ctrl |= val;
348
+
349
+ if (dwmac->f2h_ptp_ref_clk ||
350
+ phymode == PHY_INTERFACE_MODE_MII ||
351
+ phymode == PHY_INTERFACE_MODE_GMII ||
352
+ phymode == PHY_INTERFACE_MODE_SGMII) {
353
+ ctrl |= SYSMGR_GEN10_EMACGRP_CTRL_PTP_REF_CLK_MASK;
354
+ regmap_read(sys_mgr_base_addr, SYSMGR_FPGAINTF_EMAC_REG,
355
+ &module);
356
+ module |= (SYSMGR_FPGAINTF_EMAC_BIT << reg_shift);
357
+ regmap_write(sys_mgr_base_addr, SYSMGR_FPGAINTF_EMAC_REG,
358
+ module);
359
+ } else {
360
+ ctrl &= ~SYSMGR_GEN10_EMACGRP_CTRL_PTP_REF_CLK_MASK;
361
+ }
362
+
363
+ regmap_write(sys_mgr_base_addr, reg_offset, ctrl);
364
+
365
+ /* Deassert reset for the phy configuration to be sampled by
366
+ * the enet controller, and operation to start in requested mode
367
+ */
368
+ reset_control_deassert(dwmac->stmmac_ocp_rst);
369
+ reset_control_deassert(dwmac->stmmac_rst);
370
+ if (phymode == PHY_INTERFACE_MODE_SGMII) {
371
+ if (tse_pcs_init(dwmac->pcs.tse_pcs_base, &dwmac->pcs) != 0) {
372
+ dev_err(dwmac->dev, "Unable to initialize TSE PCS");
373
+ return -EINVAL;
374
+ }
375
+ }
376
+ return 0;
377
+}
378
+
307379 static int socfpga_dwmac_probe(struct platform_device *pdev)
308380 {
309381 struct plat_stmmacenet_data *plat_dat;
....@@ -313,6 +385,13 @@
313385 struct socfpga_dwmac *dwmac;
314386 struct net_device *ndev;
315387 struct stmmac_priv *stpriv;
388
+ const struct socfpga_dwmac_ops *ops;
389
+
390
+ ops = device_get_match_data(&pdev->dev);
391
+ if (!ops) {
392
+ dev_err(&pdev->dev, "no of match data provided\n");
393
+ return -EINVAL;
394
+ }
316395
317396 ret = stmmac_get_platform_resources(pdev, &stmmac_res);
318397 if (ret)
....@@ -343,6 +422,7 @@
343422 goto err_remove_config_dt;
344423 }
345424
425
+ dwmac->ops = ops;
346426 plat_dat->bsp_priv = dwmac;
347427 plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed;
348428
....@@ -359,7 +439,7 @@
359439 */
360440 dwmac->stmmac_rst = stpriv->plat->stmmac_rst;
361441
362
- ret = socfpga_dwmac_set_phy_mode(dwmac);
442
+ ret = ops->set_phy_mode(dwmac);
363443 if (ret)
364444 goto err_dvr_remove;
365445
....@@ -378,8 +458,9 @@
378458 {
379459 struct net_device *ndev = dev_get_drvdata(dev);
380460 struct stmmac_priv *priv = netdev_priv(ndev);
461
+ struct socfpga_dwmac *dwmac_priv = get_stmmac_bsp_priv(dev);
381462
382
- socfpga_dwmac_set_phy_mode(priv->plat->bsp_priv);
463
+ dwmac_priv->ops->set_phy_mode(priv->plat->bsp_priv);
383464
384465 /* Before the enet controller is suspended, the phy is suspended.
385466 * This causes the phy clock to be gated. The enet controller is
....@@ -403,11 +484,40 @@
403484 }
404485 #endif /* CONFIG_PM_SLEEP */
405486
406
-static SIMPLE_DEV_PM_OPS(socfpga_dwmac_pm_ops, stmmac_suspend,
407
- socfpga_dwmac_resume);
487
+static int __maybe_unused socfpga_dwmac_runtime_suspend(struct device *dev)
488
+{
489
+ struct net_device *ndev = dev_get_drvdata(dev);
490
+ struct stmmac_priv *priv = netdev_priv(ndev);
491
+
492
+ stmmac_bus_clks_config(priv, false);
493
+
494
+ return 0;
495
+}
496
+
497
+static int __maybe_unused socfpga_dwmac_runtime_resume(struct device *dev)
498
+{
499
+ struct net_device *ndev = dev_get_drvdata(dev);
500
+ struct stmmac_priv *priv = netdev_priv(ndev);
501
+
502
+ return stmmac_bus_clks_config(priv, true);
503
+}
504
+
505
+static const struct dev_pm_ops socfpga_dwmac_pm_ops = {
506
+ SET_SYSTEM_SLEEP_PM_OPS(stmmac_suspend, socfpga_dwmac_resume)
507
+ SET_RUNTIME_PM_OPS(socfpga_dwmac_runtime_suspend, socfpga_dwmac_runtime_resume, NULL)
508
+};
509
+
510
+static const struct socfpga_dwmac_ops socfpga_gen5_ops = {
511
+ .set_phy_mode = socfpga_gen5_set_phy_mode,
512
+};
513
+
514
+static const struct socfpga_dwmac_ops socfpga_gen10_ops = {
515
+ .set_phy_mode = socfpga_gen10_set_phy_mode,
516
+};
408517
409518 static const struct of_device_id socfpga_dwmac_match[] = {
410
- { .compatible = "altr,socfpga-stmmac" },
519
+ { .compatible = "altr,socfpga-stmmac", .data = &socfpga_gen5_ops },
520
+ { .compatible = "altr,socfpga-stmmac-a10-s10", .data = &socfpga_gen10_ops },
411521 { }
412522 };
413523 MODULE_DEVICE_TABLE(of, socfpga_dwmac_match);