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/20250925191600.3306595-1-wens@kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>pull/1354/merge
commit
936f160a95
|
|
@ -10,6 +10,21 @@ maintainers:
|
|||
- Chen-Yu Tsai <wens@csie.org>
|
||||
- Maxime Ripard <mripard@kernel.org>
|
||||
|
||||
# We need a select here so we don't match all nodes with 'snps,dwmac'
|
||||
select:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- allwinner,sun8i-a83t-emac
|
||||
- allwinner,sun8i-h3-emac
|
||||
- allwinner,sun8i-r40-gmac
|
||||
- allwinner,sun8i-v3s-emac
|
||||
- allwinner,sun50i-a64-emac
|
||||
- allwinner,sun55i-a523-gmac200
|
||||
required:
|
||||
- compatible
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
|
|
@ -26,6 +41,9 @@ properties:
|
|||
- allwinner,sun50i-h616-emac0
|
||||
- allwinner,sun55i-a523-gmac0
|
||||
- const: allwinner,sun50i-a64-emac
|
||||
- items:
|
||||
- const: allwinner,sun55i-a523-gmac200
|
||||
- const: snps,dwmac-4.20a
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
@ -37,14 +55,21 @@ properties:
|
|||
const: macirq
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
const: stmmaceth
|
||||
minItems: 1
|
||||
items:
|
||||
- const: stmmaceth
|
||||
- const: mbus
|
||||
|
||||
phy-supply:
|
||||
description: PHY regulator
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
syscon:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
|
|
@ -191,6 +216,42 @@ allOf:
|
|||
- mdio-parent-bus
|
||||
- mdio@1
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: allwinner,sun55i-a523-gmac200
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 2
|
||||
clock-names:
|
||||
minItems: 2
|
||||
tx-internal-delay-ps:
|
||||
default: 0
|
||||
minimum: 0
|
||||
maximum: 700
|
||||
multipleOf: 100
|
||||
description:
|
||||
External RGMII PHY TX clock delay chain value in ps.
|
||||
rx-internal-delay-ps:
|
||||
default: 0
|
||||
minimum: 0
|
||||
maximum: 3100
|
||||
multipleOf: 100
|
||||
description:
|
||||
External RGMII PHY TX clock delay chain value in ps.
|
||||
required:
|
||||
- power-domains
|
||||
else:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 1
|
||||
clock-names:
|
||||
maxItems: 1
|
||||
power-domains: false
|
||||
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
|
@ -323,4 +384,34 @@ examples:
|
|||
};
|
||||
};
|
||||
|
||||
- |
|
||||
ethernet@4510000 {
|
||||
compatible = "allwinner,sun55i-a523-gmac200",
|
||||
"snps,dwmac-4.20a";
|
||||
reg = <0x04510000 0x10000>;
|
||||
clocks = <&ccu 117>, <&ccu 79>;
|
||||
clock-names = "stmmaceth", "mbus";
|
||||
resets = <&ccu 43>;
|
||||
reset-names = "stmmaceth";
|
||||
interrupts = <0 47 4>;
|
||||
interrupt-names = "macirq";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&rgmii1_pins>;
|
||||
power-domains = <&pck600 4>;
|
||||
syscon = <&syscon>;
|
||||
phy-handle = <&ext_rgmii_phy_1>;
|
||||
phy-mode = "rgmii-id";
|
||||
snps,fixed-burst;
|
||||
snps,axi-config = <&gmac1_stmmac_axi_setup>;
|
||||
|
||||
mdio {
|
||||
compatible = "snps,dwmac-mdio";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ext_rgmii_phy_1: ethernet-phy@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
|
|||
|
|
@ -265,6 +265,18 @@ config DWMAC_SUN8I
|
|||
stmmac device driver. This driver is used for H3/A83T/A64
|
||||
EMAC ethernet controller.
|
||||
|
||||
config DWMAC_SUN55I
|
||||
tristate "Allwinner sun55i GMAC200 support"
|
||||
default ARCH_SUNXI
|
||||
depends on OF && (ARCH_SUNXI || COMPILE_TEST)
|
||||
select MDIO_BUS_MUX
|
||||
help
|
||||
Support for Allwinner A523/T527 GMAC200 ethernet controllers.
|
||||
|
||||
This selects Allwinner SoC glue layer support for the
|
||||
stmmac device driver. This driver is used for A523/T527
|
||||
GMAC200 ethernet controller.
|
||||
|
||||
config DWMAC_THEAD
|
||||
tristate "T-HEAD dwmac support"
|
||||
depends on OF && (ARCH_THEAD || COMPILE_TEST)
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o
|
|||
obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o
|
||||
obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
|
||||
obj-$(CONFIG_DWMAC_SUN8I) += dwmac-sun8i.o
|
||||
obj-$(CONFIG_DWMAC_SUN55I) += dwmac-sun55i.o
|
||||
obj-$(CONFIG_DWMAC_THEAD) += dwmac-thead.o
|
||||
obj-$(CONFIG_DWMAC_DWC_QOS_ETH) += dwmac-dwc-qos-eth.o
|
||||
obj-$(CONFIG_DWMAC_INTEL_PLAT) += dwmac-intel-plat.o
|
||||
|
|
|
|||
|
|
@ -0,0 +1,159 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* dwmac-sun55i.c - Allwinner sun55i GMAC200 specific glue layer
|
||||
*
|
||||
* Copyright (C) 2025 Chen-Yu Tsai <wens@csie.org>
|
||||
*
|
||||
* syscon parts taken from dwmac-sun8i.c, which is
|
||||
*
|
||||
* Copyright (C) 2017 Corentin Labbe <clabbe.montjoie@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/stmmac.h>
|
||||
|
||||
#include "stmmac.h"
|
||||
#include "stmmac_platform.h"
|
||||
|
||||
#define SYSCON_REG 0x34
|
||||
|
||||
/* RMII specific bits */
|
||||
#define SYSCON_RMII_EN BIT(13) /* 1: enable RMII (overrides EPIT) */
|
||||
/* Generic system control EMAC_CLK bits */
|
||||
#define SYSCON_ETXDC_MASK GENMASK(12, 10)
|
||||
#define SYSCON_ERXDC_MASK GENMASK(9, 5)
|
||||
/* EMAC PHY Interface Type */
|
||||
#define SYSCON_EPIT BIT(2) /* 1: RGMII, 0: MII */
|
||||
#define SYSCON_ETCS_MASK GENMASK(1, 0)
|
||||
#define SYSCON_ETCS_MII 0x0
|
||||
#define SYSCON_ETCS_EXT_GMII 0x1
|
||||
#define SYSCON_ETCS_INT_GMII 0x2
|
||||
|
||||
static int sun55i_gmac200_set_syscon(struct device *dev,
|
||||
struct plat_stmmacenet_data *plat)
|
||||
{
|
||||
struct device_node *node = dev->of_node;
|
||||
struct regmap *regmap;
|
||||
u32 val, reg = 0;
|
||||
int ret;
|
||||
|
||||
regmap = syscon_regmap_lookup_by_phandle(node, "syscon");
|
||||
if (IS_ERR(regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(regmap), "Unable to map syscon\n");
|
||||
|
||||
if (!of_property_read_u32(node, "tx-internal-delay-ps", &val)) {
|
||||
if (val % 100)
|
||||
return dev_err_probe(dev, -EINVAL,
|
||||
"tx-delay must be a multiple of 100ps\n");
|
||||
val /= 100;
|
||||
dev_dbg(dev, "set tx-delay to %x\n", val);
|
||||
if (!FIELD_FIT(SYSCON_ETXDC_MASK, val))
|
||||
return dev_err_probe(dev, -EINVAL,
|
||||
"TX clock delay exceeds maximum (%u00ps > %lu00ps)\n",
|
||||
val, FIELD_MAX(SYSCON_ETXDC_MASK));
|
||||
|
||||
reg |= FIELD_PREP(SYSCON_ETXDC_MASK, val);
|
||||
}
|
||||
|
||||
if (!of_property_read_u32(node, "rx-internal-delay-ps", &val)) {
|
||||
if (val % 100)
|
||||
return dev_err_probe(dev, -EINVAL,
|
||||
"rx-delay must be a multiple of 100ps\n");
|
||||
val /= 100;
|
||||
dev_dbg(dev, "set rx-delay to %x\n", val);
|
||||
if (!FIELD_FIT(SYSCON_ERXDC_MASK, val))
|
||||
return dev_err_probe(dev, -EINVAL,
|
||||
"RX clock delay exceeds maximum (%u00ps > %lu00ps)\n",
|
||||
val, FIELD_MAX(SYSCON_ERXDC_MASK));
|
||||
|
||||
reg |= FIELD_PREP(SYSCON_ERXDC_MASK, val);
|
||||
}
|
||||
|
||||
switch (plat->phy_interface) {
|
||||
case PHY_INTERFACE_MODE_MII:
|
||||
/* default */
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_RGMII:
|
||||
case PHY_INTERFACE_MODE_RGMII_ID:
|
||||
case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||
case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||
reg |= SYSCON_EPIT | SYSCON_ETCS_INT_GMII;
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_RMII:
|
||||
reg |= SYSCON_RMII_EN;
|
||||
break;
|
||||
default:
|
||||
return dev_err_probe(dev, -EINVAL, "Unsupported interface mode: %s",
|
||||
phy_modes(plat->phy_interface));
|
||||
}
|
||||
|
||||
ret = regmap_write(regmap, SYSCON_REG, reg);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret, "Failed to write to syscon\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sun55i_gmac200_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct plat_stmmacenet_data *plat_dat;
|
||||
struct stmmac_resources stmmac_res;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
|
||||
ret = stmmac_get_platform_resources(pdev, &stmmac_res);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
|
||||
if (IS_ERR(plat_dat))
|
||||
return PTR_ERR(plat_dat);
|
||||
|
||||
/* BSP disables it */
|
||||
plat_dat->flags |= STMMAC_FLAG_SPH_DISABLE;
|
||||
plat_dat->host_dma_width = 32;
|
||||
|
||||
ret = sun55i_gmac200_set_syscon(dev, plat_dat);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clk = devm_clk_get_enabled(dev, "mbus");
|
||||
if (IS_ERR(clk))
|
||||
return dev_err_probe(dev, PTR_ERR(clk),
|
||||
"Failed to get or enable MBUS clock\n");
|
||||
|
||||
ret = devm_regulator_get_enable_optional(dev, "phy");
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to get or enable PHY supply\n");
|
||||
|
||||
return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
|
||||
}
|
||||
|
||||
static const struct of_device_id sun55i_gmac200_match[] = {
|
||||
{ .compatible = "allwinner,sun55i-a523-gmac200" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sun55i_gmac200_match);
|
||||
|
||||
static struct platform_driver sun55i_gmac200_driver = {
|
||||
.probe = sun55i_gmac200_probe,
|
||||
.driver = {
|
||||
.name = "dwmac-sun55i",
|
||||
.pm = &stmmac_pltfr_pm_ops,
|
||||
.of_match_table = sun55i_gmac200_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(sun55i_gmac200_driver);
|
||||
|
||||
MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
|
||||
MODULE_DESCRIPTION("Allwinner sun55i GMAC200 specific glue layer");
|
||||
MODULE_LICENSE("GPL");
|
||||
Loading…
Reference in New Issue