Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'add-support-for-nuvoton-ma35d1-gmac'

Joey Lu says:

====================
Add support for Nuvoton MA35D1 GMAC

This patch series is submitted to add GMAC support for Nuvoton MA35D1
SoC platform. This work involves implementing a GMAC driver glue layer
based on Synopsys DWMAC driver framework to leverage MA35D1's dual GMAC
interface capabilities.

Overview:
1. Added a GMAC driver glue layer for MA35D1 SoC, providing support for
the platform's two GMAC interfaces.
2. Added device tree settings, with specific configurations for our
development boards:
a. SOM board: Configured for two RGMII interfaces.
b. IoT board: Configured with one RGMII and one RMII interface.
3. Added dt-bindings for the GMAC interfaces.
====================

Link: https://patch.msgid.link/20260323101756.81849-1-a0987203069@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+290
+140
Documentation/devicetree/bindings/net/nuvoton,ma35d1-dwmac.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/net/nuvoton,ma35d1-dwmac.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Nuvoton DWMAC glue layer controller 8 + 9 + maintainers: 10 + - Joey Lu <yclu4@nuvoton.com> 11 + 12 + description: 13 + Nuvoton 10/100/1000Mbps Gigabit Ethernet MAC Controller is based on 14 + Synopsys DesignWare MAC (version 3.73a). 15 + 16 + select: 17 + properties: 18 + compatible: 19 + contains: 20 + enum: 21 + - nuvoton,ma35d1-dwmac 22 + required: 23 + - compatible 24 + 25 + allOf: 26 + - $ref: snps,dwmac.yaml# 27 + 28 + properties: 29 + compatible: 30 + items: 31 + - const: nuvoton,ma35d1-dwmac 32 + - const: snps,dwmac-3.70a 33 + 34 + reg: 35 + maxItems: 1 36 + description: 37 + Register range should be one of the GMAC interface. 38 + 39 + interrupts: 40 + maxItems: 1 41 + 42 + clocks: 43 + items: 44 + - description: MAC clock 45 + - description: PTP clock 46 + 47 + clock-names: 48 + items: 49 + - const: stmmaceth 50 + - const: ptp_ref 51 + 52 + nuvoton,sys: 53 + $ref: /schemas/types.yaml#/definitions/phandle-array 54 + items: 55 + - items: 56 + - description: phandle to access syscon registers. 57 + - description: GMAC interface ID. 58 + enum: 59 + - 0 60 + - 1 61 + description: 62 + A phandle to the syscon with one argument that configures system registers 63 + for MA35D1's two GMACs. The argument specifies the GMAC interface ID. 64 + 65 + resets: 66 + maxItems: 1 67 + 68 + reset-names: 69 + items: 70 + - const: stmmaceth 71 + 72 + phy-mode: 73 + enum: 74 + - rmii 75 + - rgmii 76 + - rgmii-id 77 + - rgmii-txid 78 + - rgmii-rxid 79 + 80 + tx-internal-delay-ps: 81 + default: 0 82 + minimum: 0 83 + maximum: 2000 84 + description: 85 + RGMII TX path delay used only when PHY operates in RGMII mode with 86 + internal delay (phy-mode is 'rgmii-id' or 'rgmii-txid') in pico-seconds. 87 + Allowed values are from 0 to 2000. 88 + 89 + rx-internal-delay-ps: 90 + default: 0 91 + minimum: 0 92 + maximum: 2000 93 + description: 94 + RGMII RX path delay used only when PHY operates in RGMII mode with 95 + internal delay (phy-mode is 'rgmii-id' or 'rgmii-rxid') in pico-seconds. 96 + Allowed values are from 0 to 2000. 97 + 98 + required: 99 + - clocks 100 + - clock-names 101 + - nuvoton,sys 102 + - resets 103 + - reset-names 104 + - phy-mode 105 + 106 + unevaluatedProperties: false 107 + 108 + examples: 109 + - | 110 + #include <dt-bindings/interrupt-controller/arm-gic.h> 111 + #include <dt-bindings/clock/nuvoton,ma35d1-clk.h> 112 + #include <dt-bindings/reset/nuvoton,ma35d1-reset.h> 113 + ethernet@40120000 { 114 + compatible = "nuvoton,ma35d1-dwmac", "snps,dwmac-3.70a"; 115 + reg = <0x40120000 0x10000>; 116 + interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>; 117 + interrupt-names = "macirq"; 118 + clocks = <&clk EMAC0_GATE>, <&clk EPLL_DIV8>; 119 + clock-names = "stmmaceth", "ptp_ref"; 120 + 121 + nuvoton,sys = <&sys 0>; 122 + resets = <&sys MA35D1_RESET_GMAC0>; 123 + reset-names = "stmmaceth"; 124 + snps,multicast-filter-bins = <0>; 125 + snps,perfect-filter-entries = <8>; 126 + rx-fifo-depth = <4096>; 127 + tx-fifo-depth = <2048>; 128 + 129 + phy-mode = "rgmii-id"; 130 + phy-handle = <&eth_phy0>; 131 + mdio { 132 + compatible = "snps,dwmac-mdio"; 133 + #address-cells = <1>; 134 + #size-cells = <0>; 135 + 136 + eth_phy0: ethernet-phy@0 { 137 + reg = <0>; 138 + }; 139 + }; 140 + };
+1
Documentation/devicetree/bindings/net/snps,dwmac.yaml
··· 69 69 - ingenic,x2000-mac 70 70 - loongson,ls2k-dwmac 71 71 - loongson,ls7a-dwmac 72 + - nuvoton,ma35d1-dwmac 72 73 - nxp,s32g2-dwmac 73 74 - qcom,qcs404-ethqos 74 75 - qcom,sa8775p-ethqos
+12
drivers/net/ethernet/stmicro/stmmac/Kconfig
··· 132 132 the stmmac device driver. This driver is used for Meson6, 133 133 Meson8, Meson8b and GXBB SoCs. 134 134 135 + config DWMAC_NUVOTON 136 + tristate "Nuvoton MA35 dwmac support" 137 + default ARCH_MA35 138 + depends on OF && (ARCH_MA35 || COMPILE_TEST) 139 + select MFD_SYSCON 140 + help 141 + Support for Ethernet controller on Nuvoton MA35 series SoC. 142 + 143 + This selects the Nuvoton MA35 series SoC glue layer support 144 + for the stmmac device driver. The nuvoton-dwmac driver is 145 + used for MA35 series SoCs. 146 + 135 147 config DWMAC_QCOM_ETHQOS 136 148 tristate "Qualcomm ETHQOS support" 137 149 default ARCH_QCOM
+1
drivers/net/ethernet/stmicro/stmmac/Makefile
··· 20 20 obj-$(CONFIG_DWMAC_LPC18XX) += dwmac-lpc18xx.o 21 21 obj-$(CONFIG_DWMAC_MEDIATEK) += dwmac-mediatek.o 22 22 obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o dwmac-meson8b.o 23 + obj-$(CONFIG_DWMAC_NUVOTON) += dwmac-nuvoton.o 23 24 obj-$(CONFIG_DWMAC_QCOM_ETHQOS) += dwmac-qcom-ethqos.o 24 25 obj-$(CONFIG_DWMAC_RENESAS_GBETH) += dwmac-renesas-gbeth.o 25 26 obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o
+136
drivers/net/ethernet/stmicro/stmmac/dwmac-nuvoton.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Nuvoton DWMAC specific glue layer 4 + * 5 + * Copyright (C) 2025 Nuvoton Technology Corp. 6 + * 7 + * Author: Joey Lu <a0987203069@gmail.com> 8 + */ 9 + 10 + #include <linux/mfd/syscon.h> 11 + #include <linux/mod_devicetable.h> 12 + #include <linux/of.h> 13 + #include <linux/of_net.h> 14 + #include <linux/platform_device.h> 15 + #include <linux/regmap.h> 16 + #include <linux/stmmac.h> 17 + 18 + #include "stmmac_platform.h" 19 + 20 + #define NVT_REG_SYS_GMAC0MISCR 0x108 21 + #define NVT_REG_SYS_GMAC1MISCR 0x10C 22 + 23 + #define NVT_MISCR_RMII BIT(0) 24 + 25 + /* Two thousand picoseconds are evenly mapped to a 4-bit field, 26 + * resulting in each step being 2000/15 picoseconds. 27 + */ 28 + #define NVT_PATH_DELAY_STEP 134 29 + #define NVT_TX_DELAY_MASK GENMASK(19, 16) 30 + #define NVT_RX_DELAY_MASK GENMASK(23, 20) 31 + 32 + struct nvt_priv_data { 33 + struct device *dev; 34 + struct regmap *regmap; 35 + u32 macid; 36 + }; 37 + 38 + static int nvt_gmac_get_delay(struct device *dev, const char *property) 39 + { 40 + u32 arg; 41 + 42 + if (of_property_read_u32(dev->of_node, property, &arg)) 43 + return 0; 44 + 45 + if (arg > 2000) 46 + return -EINVAL; 47 + 48 + if (arg == 2000) 49 + return 15; 50 + 51 + return arg / NVT_PATH_DELAY_STEP; 52 + } 53 + 54 + static int nvt_set_phy_intf_sel(void *bsp_priv, u8 phy_intf_sel) 55 + { 56 + struct nvt_priv_data *priv = bsp_priv; 57 + u32 reg, val; 58 + int ret; 59 + 60 + if (phy_intf_sel == PHY_INTF_SEL_RGMII) { 61 + ret = nvt_gmac_get_delay(priv->dev, "rx-internal-delay-ps"); 62 + if (ret < 0) 63 + return ret; 64 + val = FIELD_PREP(NVT_RX_DELAY_MASK, ret); 65 + 66 + ret = nvt_gmac_get_delay(priv->dev, "tx-internal-delay-ps"); 67 + if (ret < 0) 68 + return ret; 69 + val |= FIELD_PREP(NVT_TX_DELAY_MASK, ret); 70 + } else if (phy_intf_sel == PHY_INTF_SEL_RMII) { 71 + val = NVT_MISCR_RMII; 72 + } else { 73 + return -EINVAL; 74 + } 75 + 76 + reg = (priv->macid == 0) ? NVT_REG_SYS_GMAC0MISCR : NVT_REG_SYS_GMAC1MISCR; 77 + regmap_update_bits(priv->regmap, reg, 78 + NVT_RX_DELAY_MASK | NVT_TX_DELAY_MASK | NVT_MISCR_RMII, val); 79 + 80 + return 0; 81 + } 82 + 83 + static int nvt_gmac_probe(struct platform_device *pdev) 84 + { 85 + struct plat_stmmacenet_data *plat_dat; 86 + struct stmmac_resources stmmac_res; 87 + struct device *dev = &pdev->dev; 88 + struct nvt_priv_data *priv; 89 + int ret; 90 + 91 + ret = stmmac_get_platform_resources(pdev, &stmmac_res); 92 + if (ret) 93 + return dev_err_probe(dev, ret, "Failed to get platform resources\n"); 94 + 95 + plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac); 96 + if (IS_ERR(plat_dat)) 97 + return dev_err_probe(dev, PTR_ERR(plat_dat), "Failed to get platform data\n"); 98 + 99 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 100 + if (!priv) 101 + return dev_err_probe(dev, -ENOMEM, "Failed to allocate private data\n"); 102 + 103 + priv->regmap = syscon_regmap_lookup_by_phandle_args(dev->of_node, "nuvoton,sys", 104 + 1, &priv->macid); 105 + if (IS_ERR(priv->regmap)) 106 + return dev_err_probe(dev, PTR_ERR(priv->regmap), "Failed to get sys register\n"); 107 + 108 + if (priv->macid > 1) 109 + return dev_err_probe(dev, -EINVAL, "Invalid sys arguments\n"); 110 + 111 + plat_dat->bsp_priv = priv; 112 + plat_dat->set_phy_intf_sel = nvt_set_phy_intf_sel; 113 + 114 + return stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res); 115 + } 116 + 117 + static const struct of_device_id nvt_dwmac_match[] = { 118 + { .compatible = "nuvoton,ma35d1-dwmac"}, 119 + { } 120 + }; 121 + MODULE_DEVICE_TABLE(of, nvt_dwmac_match); 122 + 123 + static struct platform_driver nvt_dwmac_driver = { 124 + .probe = nvt_gmac_probe, 125 + .remove = stmmac_pltfr_remove, 126 + .driver = { 127 + .name = "nuvoton-dwmac", 128 + .pm = &stmmac_pltfr_pm_ops, 129 + .of_match_table = nvt_dwmac_match, 130 + }, 131 + }; 132 + module_platform_driver(nvt_dwmac_driver); 133 + 134 + MODULE_AUTHOR("Joey Lu <a0987203069@gmail.com>"); 135 + MODULE_DESCRIPTION("Nuvoton DWMAC specific glue layer"); 136 + MODULE_LICENSE("GPL");