Re: [PATCH net-next v3 3/3] net: stmmac: Add glue layer for Spacemit K3 SoC
From: Vivian Wang <hidden>
Date: 2026-01-28 09:17:31
Also in:
linux-arm-kernel, linux-devicetree, linux-riscv, lkml, spacemit
Hi Inochi, I have some comments below. On 1/28/26 15:29, Inochi Amaoto wrote:
The etherenet controller on Spacemit K3 SoC is Synopsys DesignWare
Typo: etherenet -> ethernet
MAC (version 5.40a), with the following special point:
Nit: point -> points
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.