Re: [PATCH net-next 3/3] net: stmmac: Add glue layer for Spacemit K3 SoC
From: Inochi Amaoto <inochiama@gmail.com>
Date: 2026-01-20 11:41:44
Also in:
linux-devicetree, linux-riscv, lkml, netdev, spacemit
On Tue, Jan 20, 2026 at 11:13:50AM +0000, Yao Zi wrote:
On Tue, Jan 20, 2026 at 12:36:08PM +0800, Inochi Amaoto wrote:quoted
Adds Spacemit dwmac driver support on the Spacemit K3 SoC. Signed-off-by: Inochi Amaoto <inochiama@gmail.com> --- drivers/net/ethernet/stmicro/stmmac/Kconfig | 12 + drivers/net/ethernet/stmicro/stmmac/Makefile | 1 + .../ethernet/stmicro/stmmac/dwmac-spacemit.c | 224 ++++++++++++++++++ 3 files changed, 237 insertions(+) create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-spacemit.c...quoted
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-spacemit.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-spacemit.c new file mode 100644 index 000000000000..72744e60d02a --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-spacemit.c@@ -0,0 +1,224 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Spacemit DWMAC platform driver + * + * Copyright (C) 2026 Inochi Amaoto <inochiama@gmail.com> + */ + +#include <linux/clk.h> +#include <linux/mfd/syscon.h> +#include <linux/math.h>These are the only two headers listed out-of-order. Is this intended?
I will fix this.
quoted
+#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/property.h> +#include <linux/regmap.h>...quoted
+static int spacemit_dwmac_detected_delay_value(unsigned int delay, + unsigned int *config) +{ + int i; + int code, best_code = 0; + unsigned int best_delay = 0; + unsigned int best_config = 0; + + if (delay == 0) + return 0; + + for (i = 0; i < ARRAY_SIZE(k3_delay_step_10x); i++) { + unsigned int step = k3_delay_step_10x[i]; + + for (code = 1; code <= MAX_DLINE_DELAY_CODE; code++) { + /* + * Note K3 require a specific factor for calculate + * the delay, in this scenario it is 0.9. So the + * formula is code * step / 10 * 0.9 + */ + unsigned int tmp = code * step * 9 / 10 / 10; + + if (abs(tmp - delay) < abs(best_delay - delay)) { + best_code = code; + best_delay = tmp; + best_config = i; + }Is the inner loop really necessary? Could it be replaced by this_code = DIV_ROUND_CLOSEST(delay * 10 * 10, step * 9); this_delay = this_code * step * 9 / 10 / 10; Then comparing abs(this_delay - delay) and abs(best_delay - delay)?
This is a good idea, thanks.
quoted
+ } + } + + *config = best_config; + + return best_code; +}...quoted
+static int spacemit_dwmac_update_ifconfig(struct plat_stmmacenet_data *plat_dat, + struct stmmac_resources *stmmac_res, + struct regmap *apmu, + unsigned int ctrl_offset) +{ + unsigned int mask = PHY_INTF_MII | PHY_INTF_RGMII | WAKE_IRQ_EN; + unsigned int val = 0; + + switch (plat_dat->phy_interface) { + case PHY_INTERFACE_MODE_MII: + val |= PHY_INTF_MII; + break;The OR operation seems unnecessary and could be replaced with an assignment. Same for PHY_INTERFACE_MODE_RGMII's case.
That's tree, an assignment is better than the OR operation, I will change this in the next version.
quoted
+ + case PHY_INTERFACE_MODE_RMII: + break; + + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_TXID: + val |= PHY_INTF_RGMII; + break; + + default: + return -EOPNOTSUPP; + }...quoted
+static int spacemit_dwmac_probe(struct platform_device *pdev) +{...quoted
+ of_property_read_u32(pdev->dev.of_node, "tx-internal-delay-ps", &tx_delay); + of_property_read_u32(pdev->dev.of_node, "rx-internal-delay-ps", &rx_delay);According to of.h, of_property_read_u32, which in turn calls of_property_read_u32_array, could fail with -ENODATA if there's no value associated with the property. Should the case be handled? Regards, Yao Zi