Re: [PATCH net-next v3 3/3] net: stmmac: Add glue layer for Spacemit K3 SoC
From: Inochi Amaoto <inochiama@gmail.com>
Date: 2026-01-28 11:22:22
Also in:
linux-devicetree, linux-riscv, lkml, netdev, spacemit
On Wed, Jan 28, 2026 at 05:16:46PM +0800, Vivian Wang wrote:
Hi Inochi, I have some comments below. On 1/28/26 15:29, Inochi Amaoto wrote:quoted
The etherenet controller on Spacemit K3 SoC is Synopsys DesignWareTypo: etherenet -> ethernetquoted
MAC (version 5.40a), with the following special point:Nit: point -> points
Thanks
quoted
1. The rate of the tx clock line is auto changed when the mac speed rate is changed, and no need for changing the input tx clock. 2. This controller require a extra syscon device to configure the interface type, enable wake up interrupt and delay configuration if needed. Add 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 | 218 ++++++++++++++++++ 3 files changed, 231 insertions(+) create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-spacemit.c [...] + +/* dline register bits */ +#define RGMII_RX_DLINE_EN BIT(0) +#define RGMII_RX_DLINE_STEP GENMASK(5, 4) +#define RGMII_RX_DLINE_CODE GENMASK(15, 8) +#define RGMII_TX_DLINE_EN BIT(16) +#define RGMII_TX_DLINE_STEP GENMASK(21, 20) +#define RGMII_TX_DLINE_CODE GENMASK(31, 24) + +#define MAX_DLINE_DELAY_CODE 0xff +#define MAX_WORKED_DELAY 2800 + +/* Note: the delay step value is at 0.1ps */ +static const unsigned int k3_delay_step_10x[4] = { + 367, 493, 559, 685 +}; + +static int spacemit_dwmac_set_delay(struct regmap *apmu, + unsigned int dline_offset, + unsigned int tx_code, unsigned int tx_config, + unsigned int rx_code, unsigned int rx_config) +{ + unsigned int mask, val; + + mask = RGMII_TX_DLINE_STEP | RGMII_TX_DLINE_CODE | RGMII_TX_DLINE_EN | + RGMII_RX_DLINE_STEP | RGMII_RX_DLINE_CODE | RGMII_RX_DLINE_EN; + val = FIELD_PREP(RGMII_TX_DLINE_STEP, tx_config) | + FIELD_PREP(RGMII_TX_DLINE_CODE, tx_code) | RGMII_TX_DLINE_EN | + FIELD_PREP(RGMII_RX_DLINE_STEP, rx_config) | + FIELD_PREP(RGMII_RX_DLINE_CODE, rx_code) | RGMII_RX_DLINE_EN; + + return regmap_update_bits(apmu, dline_offset, mask, val); +} + +static int spacemit_dwmac_detected_delay_value(unsigned int delay, + unsigned int *config) +{ + unsigned int best_delay = 0; + unsigned int best_config = 0; + int best_code = 0; + int i; + + if (delay == 0) + return 0; + + if (delay > MAX_WORKED_DELAY) + return -EINVAL; + + /* + * 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 + */ + for (i = 0; i < ARRAY_SIZE(k3_delay_step_10x); i++) { + unsigned int step = k3_delay_step_10x[i]; + int code = DIV_ROUND_CLOSEST(delay * 10 * 10, step * 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; + } + } + + *config = best_config; + + return best_code;Is this really necessary? For K1 I just used the smallest step size. It seems to me you have, for the smallest step size, about 36.7ps * 0.9 = 33ps per step. Theoretically speaking that lets you fine tune the delay to within 1% of the 2ns total required RGMII delay (MAC + PCB + PHY). In practice this number shouldn't be that marginal.
I think it is reasonable, I will take you advice and use the smallest step size. Regards, Inochi