Skip to content

Commit 0621be4

Browse files
committed
Merge branch 'net-stmmac-add-support-for-rzn1-gmac-devices'
Romain Gantois says: ==================== net: stmmac: Add support for RZN1 GMAC devices This is version seven of my series that adds support for a Gigabit Ethernet controller featured in the Renesas r9a06g032 SoC, of the RZ/N1 family. This GMAC device is based on a Synopsys IP and is compatible with the stmmac driver. My former colleague Clément Léger originally sent a series for this driver, but an issue in bringing up the PCS clock had blocked the upstreaming process. This issue has since been resolved by the following series: https://lore.kernel.org/all/20240326-rxc_bugfix-v6-0-24a74e5c761f@bootlin.com/ This series consists of a devicetree binding describing the RZN1 GMAC controller IP, a node for the GMAC1 device in the r9a06g032 SoC device tree, and the GMAC driver itself which is a glue layer in stmmac. There are also two patches by Russell that improve pcs initialization handling in stmmac. ==================== Link: https://lore.kernel.org/r/20240513-rzn1-gmac1-v7-0-6acf58b5440d@bootlin.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 486ffc3 + f360446 commit 0621be4

File tree

10 files changed

+272
-77
lines changed

10 files changed

+272
-77
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/net/renesas,rzn1-gmac.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: Renesas GMAC
8+
9+
maintainers:
10+
- Romain Gantois <romain.gantois@bootlin.com>
11+
12+
select:
13+
properties:
14+
compatible:
15+
contains:
16+
enum:
17+
- renesas,r9a06g032-gmac
18+
- renesas,rzn1-gmac
19+
required:
20+
- compatible
21+
22+
allOf:
23+
- $ref: snps,dwmac.yaml#
24+
25+
properties:
26+
compatible:
27+
items:
28+
- enum:
29+
- renesas,r9a06g032-gmac
30+
- const: renesas,rzn1-gmac
31+
- const: snps,dwmac
32+
33+
pcs-handle:
34+
description:
35+
phandle pointing to a PCS sub-node compatible with
36+
renesas,rzn1-miic.yaml#
37+
38+
required:
39+
- compatible
40+
41+
unevaluatedProperties: false
42+
43+
examples:
44+
- |
45+
#include <dt-bindings/clock/r9a06g032-sysctrl.h>
46+
#include <dt-bindings/interrupt-controller/arm-gic.h>
47+
48+
ethernet@44000000 {
49+
compatible = "renesas,r9a06g032-gmac", "renesas,rzn1-gmac", "snps,dwmac";
50+
reg = <0x44000000 0x2000>;
51+
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
52+
<GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
53+
<GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
54+
interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
55+
clock-names = "stmmaceth";
56+
clocks = <&sysctrl R9A06G032_HCLK_GMAC0>;
57+
power-domains = <&sysctrl>;
58+
snps,multicast-filter-bins = <256>;
59+
snps,perfect-filter-entries = <128>;
60+
tx-fifo-depth = <2048>;
61+
rx-fifo-depth = <4096>;
62+
pcs-handle = <&mii_conv1>;
63+
phy-mode = "mii";
64+
};
65+
66+
...

MAINTAINERS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18874,6 +18874,12 @@ F: include/dt-bindings/net/pcs-rzn1-miic.h
1887418874
F: include/linux/pcs-rzn1-miic.h
1887518875
F: net/dsa/tag_rzn1_a5psw.c
1887618876

18877+
RENESAS RZ/N1 DWMAC GLUE LAYER
18878+
M: Romain Gantois <romain.gantois@bootlin.com>
18879+
S: Maintained
18880+
F: Documentation/devicetree/bindings/net/renesas,rzn1-gmac.yaml
18881+
F: drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c
18882+
1887718883
RENESAS RZ/N1 RTC CONTROLLER DRIVER
1887818884
M: Miquel Raynal <miquel.raynal@bootlin.com>
1887918885
L: linux-rtc@vger.kernel.org

drivers/net/ethernet/stmicro/stmmac/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,18 @@ config DWMAC_ROCKCHIP
142142
This selects the Rockchip RK3288 SoC glue layer support for
143143
the stmmac device driver.
144144

145+
config DWMAC_RZN1
146+
tristate "Renesas RZ/N1 dwmac support"
147+
default ARCH_RZN1
148+
depends on OF && (ARCH_RZN1 || COMPILE_TEST)
149+
select PCS_RZN1_MIIC
150+
help
151+
Support for Ethernet controller on Renesas RZ/N1 SoC family.
152+
153+
This selects the Renesas RZ/N1 SoC glue layer support for
154+
the stmmac device driver. This support can make use of a custom MII
155+
converter PCS device.
156+
145157
config DWMAC_SOCFPGA
146158
tristate "SOCFPGA dwmac support"
147159
default ARCH_INTEL_SOCFPGA

drivers/net/ethernet/stmicro/stmmac/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ obj-$(CONFIG_DWMAC_MEDIATEK) += dwmac-mediatek.o
2121
obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o dwmac-meson8b.o
2222
obj-$(CONFIG_DWMAC_QCOM_ETHQOS) += dwmac-qcom-ethqos.o
2323
obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o
24+
obj-$(CONFIG_DWMAC_RZN1) += dwmac-rzn1.o
2425
obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-altr-socfpga.o
2526
obj-$(CONFIG_DWMAC_STARFIVE) += dwmac-starfive.o
2627
obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
/*
3+
* Copyright (C) 2024 Schneider-Electric
4+
*
5+
* Clément Léger <clement.leger@bootlin.com>
6+
*/
7+
8+
#include <linux/of.h>
9+
#include <linux/pcs-rzn1-miic.h>
10+
#include <linux/phylink.h>
11+
#include <linux/platform_device.h>
12+
13+
#include "stmmac_platform.h"
14+
#include "stmmac.h"
15+
16+
static int rzn1_dwmac_pcs_init(struct stmmac_priv *priv)
17+
{
18+
struct device_node *np = priv->device->of_node;
19+
struct device_node *pcs_node;
20+
struct phylink_pcs *pcs;
21+
22+
pcs_node = of_parse_phandle(np, "pcs-handle", 0);
23+
24+
if (pcs_node) {
25+
pcs = miic_create(priv->device, pcs_node);
26+
of_node_put(pcs_node);
27+
if (IS_ERR(pcs))
28+
return PTR_ERR(pcs);
29+
30+
priv->hw->phylink_pcs = pcs;
31+
}
32+
33+
return 0;
34+
}
35+
36+
static void rzn1_dwmac_pcs_exit(struct stmmac_priv *priv)
37+
{
38+
if (priv->hw->phylink_pcs)
39+
miic_destroy(priv->hw->phylink_pcs);
40+
}
41+
42+
static int rzn1_dwmac_probe(struct platform_device *pdev)
43+
{
44+
struct plat_stmmacenet_data *plat_dat;
45+
struct stmmac_resources stmmac_res;
46+
struct device *dev = &pdev->dev;
47+
int ret;
48+
49+
ret = stmmac_get_platform_resources(pdev, &stmmac_res);
50+
if (ret)
51+
return ret;
52+
53+
plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
54+
if (IS_ERR(plat_dat))
55+
return PTR_ERR(plat_dat);
56+
57+
plat_dat->bsp_priv = plat_dat;
58+
plat_dat->pcs_init = rzn1_dwmac_pcs_init;
59+
plat_dat->pcs_exit = rzn1_dwmac_pcs_exit;
60+
61+
ret = stmmac_dvr_probe(dev, plat_dat, &stmmac_res);
62+
if (ret)
63+
return ret;
64+
65+
return 0;
66+
}
67+
68+
static const struct of_device_id rzn1_dwmac_match[] = {
69+
{ .compatible = "renesas,rzn1-gmac" },
70+
{ }
71+
};
72+
MODULE_DEVICE_TABLE(of, rzn1_dwmac_match);
73+
74+
static struct platform_driver rzn1_dwmac_driver = {
75+
.probe = rzn1_dwmac_probe,
76+
.remove_new = stmmac_pltfr_remove,
77+
.driver = {
78+
.name = "rzn1-dwmac",
79+
.of_match_table = rzn1_dwmac_match,
80+
},
81+
};
82+
module_platform_driver(rzn1_dwmac_driver);
83+
84+
MODULE_AUTHOR("Clément Léger <clement.leger@bootlin.com>");
85+
MODULE_DESCRIPTION("Renesas RZN1 DWMAC specific glue layer");
86+
MODULE_LICENSE("GPL");

drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c

Lines changed: 53 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,56 @@ static int socfpga_gen10_set_phy_mode(struct socfpga_dwmac *dwmac)
379379
return 0;
380380
}
381381

382+
static int socfpga_dwmac_pcs_init(struct stmmac_priv *priv)
383+
{
384+
struct socfpga_dwmac *dwmac = priv->plat->bsp_priv;
385+
struct regmap_config pcs_regmap_cfg = {
386+
.reg_bits = 16,
387+
.val_bits = 16,
388+
.reg_shift = REGMAP_UPSHIFT(1),
389+
};
390+
struct mdio_regmap_config mrc;
391+
struct regmap *pcs_regmap;
392+
struct phylink_pcs *pcs;
393+
struct mii_bus *pcs_bus;
394+
395+
if (!dwmac->tse_pcs_base)
396+
return 0;
397+
398+
pcs_regmap = devm_regmap_init_mmio(priv->device, dwmac->tse_pcs_base,
399+
&pcs_regmap_cfg);
400+
if (IS_ERR(pcs_regmap))
401+
return PTR_ERR(pcs_regmap);
402+
403+
memset(&mrc, 0, sizeof(mrc));
404+
mrc.regmap = pcs_regmap;
405+
mrc.parent = priv->device;
406+
mrc.valid_addr = 0x0;
407+
mrc.autoscan = false;
408+
409+
/* Can't use ndev->name here because it will not have been initialised,
410+
* and in any case, the user can rename network interfaces at runtime.
411+
*/
412+
snprintf(mrc.name, MII_BUS_ID_SIZE, "%s-pcs-mii",
413+
dev_name(priv->device));
414+
pcs_bus = devm_mdio_regmap_register(priv->device, &mrc);
415+
if (IS_ERR(pcs_bus))
416+
return PTR_ERR(pcs_bus);
417+
418+
pcs = lynx_pcs_create_mdiodev(pcs_bus, 0);
419+
if (IS_ERR(pcs))
420+
return PTR_ERR(pcs);
421+
422+
priv->hw->phylink_pcs = pcs;
423+
return 0;
424+
}
425+
426+
static void socfpga_dwmac_pcs_exit(struct stmmac_priv *priv)
427+
{
428+
if (priv->hw->phylink_pcs)
429+
lynx_pcs_destroy(priv->hw->phylink_pcs);
430+
}
431+
382432
static int socfpga_dwmac_probe(struct platform_device *pdev)
383433
{
384434
struct plat_stmmacenet_data *plat_dat;
@@ -426,6 +476,8 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
426476
dwmac->ops = ops;
427477
plat_dat->bsp_priv = dwmac;
428478
plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed;
479+
plat_dat->pcs_init = socfpga_dwmac_pcs_init;
480+
plat_dat->pcs_exit = socfpga_dwmac_pcs_exit;
429481

430482
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
431483
if (ret)
@@ -444,48 +496,6 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
444496
if (ret)
445497
goto err_dvr_remove;
446498

447-
/* Create a regmap for the PCS so that it can be used by the PCS driver,
448-
* if we have such a PCS
449-
*/
450-
if (dwmac->tse_pcs_base) {
451-
struct regmap_config pcs_regmap_cfg;
452-
struct mdio_regmap_config mrc;
453-
struct regmap *pcs_regmap;
454-
struct mii_bus *pcs_bus;
455-
456-
memset(&pcs_regmap_cfg, 0, sizeof(pcs_regmap_cfg));
457-
memset(&mrc, 0, sizeof(mrc));
458-
459-
pcs_regmap_cfg.reg_bits = 16;
460-
pcs_regmap_cfg.val_bits = 16;
461-
pcs_regmap_cfg.reg_shift = REGMAP_UPSHIFT(1);
462-
463-
pcs_regmap = devm_regmap_init_mmio(&pdev->dev, dwmac->tse_pcs_base,
464-
&pcs_regmap_cfg);
465-
if (IS_ERR(pcs_regmap)) {
466-
ret = PTR_ERR(pcs_regmap);
467-
goto err_dvr_remove;
468-
}
469-
470-
mrc.regmap = pcs_regmap;
471-
mrc.parent = &pdev->dev;
472-
mrc.valid_addr = 0x0;
473-
mrc.autoscan = false;
474-
475-
snprintf(mrc.name, MII_BUS_ID_SIZE, "%s-pcs-mii", ndev->name);
476-
pcs_bus = devm_mdio_regmap_register(&pdev->dev, &mrc);
477-
if (IS_ERR(pcs_bus)) {
478-
ret = PTR_ERR(pcs_bus);
479-
goto err_dvr_remove;
480-
}
481-
482-
stpriv->hw->phylink_pcs = lynx_pcs_create_mdiodev(pcs_bus, 0);
483-
if (IS_ERR(stpriv->hw->phylink_pcs)) {
484-
ret = PTR_ERR(stpriv->hw->phylink_pcs);
485-
goto err_dvr_remove;
486-
}
487-
}
488-
489499
return 0;
490500

491501
err_dvr_remove:
@@ -494,17 +504,6 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
494504
return ret;
495505
}
496506

497-
static void socfpga_dwmac_remove(struct platform_device *pdev)
498-
{
499-
struct net_device *ndev = platform_get_drvdata(pdev);
500-
struct stmmac_priv *priv = netdev_priv(ndev);
501-
struct phylink_pcs *pcs = priv->hw->phylink_pcs;
502-
503-
stmmac_pltfr_remove(pdev);
504-
505-
lynx_pcs_destroy(pcs);
506-
}
507-
508507
#ifdef CONFIG_PM_SLEEP
509508
static int socfpga_dwmac_resume(struct device *dev)
510509
{
@@ -576,7 +575,7 @@ MODULE_DEVICE_TABLE(of, socfpga_dwmac_match);
576575

577576
static struct platform_driver socfpga_dwmac_driver = {
578577
.probe = socfpga_dwmac_probe,
579-
.remove_new = socfpga_dwmac_remove,
578+
.remove_new = stmmac_pltfr_remove,
580579
.driver = {
581580
.name = "socfpga-dwmac",
582581
.pm = &socfpga_dwmac_pm_ops,

drivers/net/ethernet/stmicro/stmmac/stmmac.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,8 @@ enum stmmac_state {
360360
int stmmac_mdio_unregister(struct net_device *ndev);
361361
int stmmac_mdio_register(struct net_device *ndev);
362362
int stmmac_mdio_reset(struct mii_bus *mii);
363-
int stmmac_xpcs_setup(struct mii_bus *mii);
363+
int stmmac_pcs_setup(struct net_device *ndev);
364+
void stmmac_pcs_clean(struct net_device *ndev);
364365
void stmmac_set_ethtool_ops(struct net_device *netdev);
365366

366367
int stmmac_init_tstamp_counter(struct stmmac_priv *priv, u32 systime_flags);

drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7754,11 +7754,9 @@ int stmmac_dvr_probe(struct device *device,
77547754
if (priv->plat->speed_mode_2500)
77557755
priv->plat->speed_mode_2500(ndev, priv->plat->bsp_priv);
77567756

7757-
if (priv->plat->mdio_bus_data && priv->plat->mdio_bus_data->has_xpcs) {
7758-
ret = stmmac_xpcs_setup(priv->mii);
7759-
if (ret)
7760-
goto error_xpcs_setup;
7761-
}
7757+
ret = stmmac_pcs_setup(ndev);
7758+
if (ret)
7759+
goto error_pcs_setup;
77627760

77637761
ret = stmmac_phy_setup(priv);
77647762
if (ret) {
@@ -7789,8 +7787,9 @@ int stmmac_dvr_probe(struct device *device,
77897787

77907788
error_netdev_register:
77917789
phylink_destroy(priv->phylink);
7792-
error_xpcs_setup:
77937790
error_phy_setup:
7791+
stmmac_pcs_clean(ndev);
7792+
error_pcs_setup:
77947793
if (priv->hw->pcs != STMMAC_PCS_TBI &&
77957794
priv->hw->pcs != STMMAC_PCS_RTBI)
77967795
stmmac_mdio_unregister(ndev);
@@ -7832,6 +7831,9 @@ void stmmac_dvr_remove(struct device *dev)
78327831
if (priv->plat->stmmac_rst)
78337832
reset_control_assert(priv->plat->stmmac_rst);
78347833
reset_control_assert(priv->plat->stmmac_ahb_rst);
7834+
7835+
stmmac_pcs_clean(ndev);
7836+
78357837
if (priv->hw->pcs != STMMAC_PCS_TBI &&
78367838
priv->hw->pcs != STMMAC_PCS_RTBI)
78377839
stmmac_mdio_unregister(ndev);

0 commit comments

Comments
 (0)