Skip to content

Commit 936f160

Browse files
author
Paolo Abeni
committed
Merge branch 'net-stmmac-add-support-for-allwinner-a523-gmac200'
Chen-Yu Tsai says: ==================== net: stmmac: Add support for Allwinner A523 GMAC200 This is v8 of my Allwinner A523 GMAC200 support series. This is based on next-20250925. This version only contains the DT binding and driver patches. The device tree patches are basically the same as the previous version. This series adds support for the second Ethernet controller found on the Allwinner A523 SoC family. This controller, dubbed GMAC200, is a DWMAC4 core with an integration layer around it. The integration layer is similar to older Allwinner generations, but with an extra memory bus gate and separate power domain. Patch 1 adds a new compatible string combo to the existing Allwinner EMAC binding. Patch 2 adds a new driver for this core and integration combo. ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
2 parents 1a98f56 + f603808 commit 936f160

File tree

4 files changed

+265
-2
lines changed

4 files changed

+265
-2
lines changed

Documentation/devicetree/bindings/net/allwinner,sun8i-a83t-emac.yaml

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,21 @@ maintainers:
1010
- Chen-Yu Tsai <[email protected]>
1111
- Maxime Ripard <[email protected]>
1212

13+
# We need a select here so we don't match all nodes with 'snps,dwmac'
14+
select:
15+
properties:
16+
compatible:
17+
contains:
18+
enum:
19+
- allwinner,sun8i-a83t-emac
20+
- allwinner,sun8i-h3-emac
21+
- allwinner,sun8i-r40-gmac
22+
- allwinner,sun8i-v3s-emac
23+
- allwinner,sun50i-a64-emac
24+
- allwinner,sun55i-a523-gmac200
25+
required:
26+
- compatible
27+
1328
properties:
1429
compatible:
1530
oneOf:
@@ -26,6 +41,9 @@ properties:
2641
- allwinner,sun50i-h616-emac0
2742
- allwinner,sun55i-a523-gmac0
2843
- const: allwinner,sun50i-a64-emac
44+
- items:
45+
- const: allwinner,sun55i-a523-gmac200
46+
- const: snps,dwmac-4.20a
2947

3048
reg:
3149
maxItems: 1
@@ -37,14 +55,21 @@ properties:
3755
const: macirq
3856

3957
clocks:
40-
maxItems: 1
58+
minItems: 1
59+
maxItems: 2
4160

4261
clock-names:
43-
const: stmmaceth
62+
minItems: 1
63+
items:
64+
- const: stmmaceth
65+
- const: mbus
4466

4567
phy-supply:
4668
description: PHY regulator
4769

70+
power-domains:
71+
maxItems: 1
72+
4873
syscon:
4974
$ref: /schemas/types.yaml#/definitions/phandle
5075
description:
@@ -191,6 +216,42 @@ allOf:
191216
- mdio-parent-bus
192217
- mdio@1
193218

219+
- if:
220+
properties:
221+
compatible:
222+
contains:
223+
const: allwinner,sun55i-a523-gmac200
224+
then:
225+
properties:
226+
clocks:
227+
minItems: 2
228+
clock-names:
229+
minItems: 2
230+
tx-internal-delay-ps:
231+
default: 0
232+
minimum: 0
233+
maximum: 700
234+
multipleOf: 100
235+
description:
236+
External RGMII PHY TX clock delay chain value in ps.
237+
rx-internal-delay-ps:
238+
default: 0
239+
minimum: 0
240+
maximum: 3100
241+
multipleOf: 100
242+
description:
243+
External RGMII PHY TX clock delay chain value in ps.
244+
required:
245+
- power-domains
246+
else:
247+
properties:
248+
clocks:
249+
maxItems: 1
250+
clock-names:
251+
maxItems: 1
252+
power-domains: false
253+
254+
194255
unevaluatedProperties: false
195256

196257
examples:
@@ -323,4 +384,34 @@ examples:
323384
};
324385
};
325386
387+
- |
388+
ethernet@4510000 {
389+
compatible = "allwinner,sun55i-a523-gmac200",
390+
"snps,dwmac-4.20a";
391+
reg = <0x04510000 0x10000>;
392+
clocks = <&ccu 117>, <&ccu 79>;
393+
clock-names = "stmmaceth", "mbus";
394+
resets = <&ccu 43>;
395+
reset-names = "stmmaceth";
396+
interrupts = <0 47 4>;
397+
interrupt-names = "macirq";
398+
pinctrl-names = "default";
399+
pinctrl-0 = <&rgmii1_pins>;
400+
power-domains = <&pck600 4>;
401+
syscon = <&syscon>;
402+
phy-handle = <&ext_rgmii_phy_1>;
403+
phy-mode = "rgmii-id";
404+
snps,fixed-burst;
405+
snps,axi-config = <&gmac1_stmmac_axi_setup>;
406+
407+
mdio {
408+
compatible = "snps,dwmac-mdio";
409+
#address-cells = <1>;
410+
#size-cells = <0>;
411+
412+
ext_rgmii_phy_1: ethernet-phy@1 {
413+
reg = <1>;
414+
};
415+
};
416+
};
326417
...

drivers/net/ethernet/stmicro/stmmac/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,18 @@ config DWMAC_SUN8I
265265
stmmac device driver. This driver is used for H3/A83T/A64
266266
EMAC ethernet controller.
267267

268+
config DWMAC_SUN55I
269+
tristate "Allwinner sun55i GMAC200 support"
270+
default ARCH_SUNXI
271+
depends on OF && (ARCH_SUNXI || COMPILE_TEST)
272+
select MDIO_BUS_MUX
273+
help
274+
Support for Allwinner A523/T527 GMAC200 ethernet controllers.
275+
276+
This selects Allwinner SoC glue layer support for the
277+
stmmac device driver. This driver is used for A523/T527
278+
GMAC200 ethernet controller.
279+
268280
config DWMAC_THEAD
269281
tristate "T-HEAD dwmac support"
270282
depends on OF && (ARCH_THEAD || COMPILE_TEST)

drivers/net/ethernet/stmicro/stmmac/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o
3131
obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o
3232
obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
3333
obj-$(CONFIG_DWMAC_SUN8I) += dwmac-sun8i.o
34+
obj-$(CONFIG_DWMAC_SUN55I) += dwmac-sun55i.o
3435
obj-$(CONFIG_DWMAC_THEAD) += dwmac-thead.o
3536
obj-$(CONFIG_DWMAC_DWC_QOS_ETH) += dwmac-dwc-qos-eth.o
3637
obj-$(CONFIG_DWMAC_INTEL_PLAT) += dwmac-intel-plat.o
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* dwmac-sun55i.c - Allwinner sun55i GMAC200 specific glue layer
4+
*
5+
* Copyright (C) 2025 Chen-Yu Tsai <[email protected]>
6+
*
7+
* syscon parts taken from dwmac-sun8i.c, which is
8+
*
9+
* Copyright (C) 2017 Corentin Labbe <[email protected]>
10+
*/
11+
12+
#include <linux/bitfield.h>
13+
#include <linux/bits.h>
14+
#include <linux/mfd/syscon.h>
15+
#include <linux/module.h>
16+
#include <linux/of.h>
17+
#include <linux/phy.h>
18+
#include <linux/platform_device.h>
19+
#include <linux/regmap.h>
20+
#include <linux/regulator/consumer.h>
21+
#include <linux/stmmac.h>
22+
23+
#include "stmmac.h"
24+
#include "stmmac_platform.h"
25+
26+
#define SYSCON_REG 0x34
27+
28+
/* RMII specific bits */
29+
#define SYSCON_RMII_EN BIT(13) /* 1: enable RMII (overrides EPIT) */
30+
/* Generic system control EMAC_CLK bits */
31+
#define SYSCON_ETXDC_MASK GENMASK(12, 10)
32+
#define SYSCON_ERXDC_MASK GENMASK(9, 5)
33+
/* EMAC PHY Interface Type */
34+
#define SYSCON_EPIT BIT(2) /* 1: RGMII, 0: MII */
35+
#define SYSCON_ETCS_MASK GENMASK(1, 0)
36+
#define SYSCON_ETCS_MII 0x0
37+
#define SYSCON_ETCS_EXT_GMII 0x1
38+
#define SYSCON_ETCS_INT_GMII 0x2
39+
40+
static int sun55i_gmac200_set_syscon(struct device *dev,
41+
struct plat_stmmacenet_data *plat)
42+
{
43+
struct device_node *node = dev->of_node;
44+
struct regmap *regmap;
45+
u32 val, reg = 0;
46+
int ret;
47+
48+
regmap = syscon_regmap_lookup_by_phandle(node, "syscon");
49+
if (IS_ERR(regmap))
50+
return dev_err_probe(dev, PTR_ERR(regmap), "Unable to map syscon\n");
51+
52+
if (!of_property_read_u32(node, "tx-internal-delay-ps", &val)) {
53+
if (val % 100)
54+
return dev_err_probe(dev, -EINVAL,
55+
"tx-delay must be a multiple of 100ps\n");
56+
val /= 100;
57+
dev_dbg(dev, "set tx-delay to %x\n", val);
58+
if (!FIELD_FIT(SYSCON_ETXDC_MASK, val))
59+
return dev_err_probe(dev, -EINVAL,
60+
"TX clock delay exceeds maximum (%u00ps > %lu00ps)\n",
61+
val, FIELD_MAX(SYSCON_ETXDC_MASK));
62+
63+
reg |= FIELD_PREP(SYSCON_ETXDC_MASK, val);
64+
}
65+
66+
if (!of_property_read_u32(node, "rx-internal-delay-ps", &val)) {
67+
if (val % 100)
68+
return dev_err_probe(dev, -EINVAL,
69+
"rx-delay must be a multiple of 100ps\n");
70+
val /= 100;
71+
dev_dbg(dev, "set rx-delay to %x\n", val);
72+
if (!FIELD_FIT(SYSCON_ERXDC_MASK, val))
73+
return dev_err_probe(dev, -EINVAL,
74+
"RX clock delay exceeds maximum (%u00ps > %lu00ps)\n",
75+
val, FIELD_MAX(SYSCON_ERXDC_MASK));
76+
77+
reg |= FIELD_PREP(SYSCON_ERXDC_MASK, val);
78+
}
79+
80+
switch (plat->phy_interface) {
81+
case PHY_INTERFACE_MODE_MII:
82+
/* default */
83+
break;
84+
case PHY_INTERFACE_MODE_RGMII:
85+
case PHY_INTERFACE_MODE_RGMII_ID:
86+
case PHY_INTERFACE_MODE_RGMII_RXID:
87+
case PHY_INTERFACE_MODE_RGMII_TXID:
88+
reg |= SYSCON_EPIT | SYSCON_ETCS_INT_GMII;
89+
break;
90+
case PHY_INTERFACE_MODE_RMII:
91+
reg |= SYSCON_RMII_EN;
92+
break;
93+
default:
94+
return dev_err_probe(dev, -EINVAL, "Unsupported interface mode: %s",
95+
phy_modes(plat->phy_interface));
96+
}
97+
98+
ret = regmap_write(regmap, SYSCON_REG, reg);
99+
if (ret < 0)
100+
return dev_err_probe(dev, ret, "Failed to write to syscon\n");
101+
102+
return 0;
103+
}
104+
105+
static int sun55i_gmac200_probe(struct platform_device *pdev)
106+
{
107+
struct plat_stmmacenet_data *plat_dat;
108+
struct stmmac_resources stmmac_res;
109+
struct device *dev = &pdev->dev;
110+
struct clk *clk;
111+
int ret;
112+
113+
ret = stmmac_get_platform_resources(pdev, &stmmac_res);
114+
if (ret)
115+
return ret;
116+
117+
plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
118+
if (IS_ERR(plat_dat))
119+
return PTR_ERR(plat_dat);
120+
121+
/* BSP disables it */
122+
plat_dat->flags |= STMMAC_FLAG_SPH_DISABLE;
123+
plat_dat->host_dma_width = 32;
124+
125+
ret = sun55i_gmac200_set_syscon(dev, plat_dat);
126+
if (ret)
127+
return ret;
128+
129+
clk = devm_clk_get_enabled(dev, "mbus");
130+
if (IS_ERR(clk))
131+
return dev_err_probe(dev, PTR_ERR(clk),
132+
"Failed to get or enable MBUS clock\n");
133+
134+
ret = devm_regulator_get_enable_optional(dev, "phy");
135+
if (ret)
136+
return dev_err_probe(dev, ret, "Failed to get or enable PHY supply\n");
137+
138+
return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
139+
}
140+
141+
static const struct of_device_id sun55i_gmac200_match[] = {
142+
{ .compatible = "allwinner,sun55i-a523-gmac200" },
143+
{ }
144+
};
145+
MODULE_DEVICE_TABLE(of, sun55i_gmac200_match);
146+
147+
static struct platform_driver sun55i_gmac200_driver = {
148+
.probe = sun55i_gmac200_probe,
149+
.driver = {
150+
.name = "dwmac-sun55i",
151+
.pm = &stmmac_pltfr_pm_ops,
152+
.of_match_table = sun55i_gmac200_match,
153+
},
154+
};
155+
module_platform_driver(sun55i_gmac200_driver);
156+
157+
MODULE_AUTHOR("Chen-Yu Tsai <[email protected]>");
158+
MODULE_DESCRIPTION("Allwinner sun55i GMAC200 specific glue layer");
159+
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)