diff mbox series

[4/4] net: stmmac: Add glue layer for Sophgo SG2044 SoC

Message ID 20241021103617.653386-5-inochiama@gmail.com (mailing list archive)
State New
Headers show
Series riscv: sophgo: Add ethernet support for SG2044 | expand

Commit Message

Inochi Amaoto Oct. 21, 2024, 10:36 a.m. UTC
Adds Sophgo dwmac driver support on the Sophgo SG2044 SoC.

Signed-off-by: Inochi Amaoto <inochiama@gmail.com>
---
 drivers/net/ethernet/stmicro/stmmac/Kconfig   |  11 ++
 drivers/net/ethernet/stmicro/stmmac/Makefile  |   1 +
 .../ethernet/stmicro/stmmac/dwmac-sophgo.c    | 132 ++++++++++++++++++
 3 files changed, 144 insertions(+)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c

Comments

Andrew Lunn Oct. 21, 2024, 12:22 p.m. UTC | #1
> +static void sophgo_dwmac_fix_mac_speed(void *priv, unsigned int speed, unsigned int mode)
> +{
> +	struct sophgo_dwmac *dwmac = priv;
> +	unsigned long rate;
> +	int ret;
> +
> +	switch (speed) {
> +	case SPEED_1000:
> +		rate = 125000000;
> +		break;
> +	case SPEED_100:
> +		rate = 25000000;
> +		break;
> +	case SPEED_10:
> +		rate = 2500000;
> +		break;
> +	default:
> +		dev_err(dwmac->dev, "invalid speed %u\n", speed);
> +		break;
> +	}

There was a helper added recently for this, since it appears
repeatedly in drivers.

> +	ret = regmap_set_bits(regmap, args[0], DWMAC_SG2044_FLAG_USE_RX_DELAY);
> +	if (ret)
> +		return dev_err_probe(&pdev->dev, ret,
> +				     "failed to set the phy rx delay\n");

Please could you explain what this delay is for. Is it the 2ns RGMII
delay?

	Andrew
Inochi Amaoto Oct. 21, 2024, 12:38 p.m. UTC | #2
On Mon, Oct 21, 2024 at 02:22:47PM +0200, Andrew Lunn wrote:
> > +static void sophgo_dwmac_fix_mac_speed(void *priv, unsigned int speed, unsigned int mode)
> > +{
> > +	struct sophgo_dwmac *dwmac = priv;
> > +	unsigned long rate;
> > +	int ret;
> > +
> > +	switch (speed) {
> > +	case SPEED_1000:
> > +		rate = 125000000;
> > +		break;
> > +	case SPEED_100:
> > +		rate = 25000000;
> > +		break;
> > +	case SPEED_10:
> > +		rate = 2500000;
> > +		break;
> > +	default:
> > +		dev_err(dwmac->dev, "invalid speed %u\n", speed);
> > +		break;
> > +	}
> 
> There was a helper added recently for this, since it appears
> repeatedly in drivers.
> 

OK, I will change it.

> > +	ret = regmap_set_bits(regmap, args[0], DWMAC_SG2044_FLAG_USE_RX_DELAY);
> > +	if (ret)
> > +		return dev_err_probe(&pdev->dev, ret,
> > +				     "failed to set the phy rx delay\n");
> 
> Please could you explain what this delay is for. Is it the 2ns RGMII
> delay?
> 
> 	Andrew

It is related to the RGMII delay. On sg2044, when the phy 
sets rx-delay, the interal mac is not set the same delay, 
so this is needed to be set.

Regards,
Inochi
Andrew Lunn Oct. 21, 2024, 1:27 p.m. UTC | #3
> It is related to the RGMII delay. On sg2044, when the phy 
> sets rx-delay, the interal mac is not set the same delay, 
> so this is needed to be set.

This is the wrong way to do it. Please look at how phy-mode should be
used, the four different "rgmii" values. Nearly everybody gets this
wrong, so there are plenty of emails from me in the netdev list about
how it should be done.

    Andrew

---
pw-bot: cr
Chen Wang Oct. 22, 2024, 12:47 a.m. UTC | #4
On 2024/10/21 18:36, Inochi Amaoto wrote:
[......]
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c
> new file mode 100644
> index 000000000000..83c67c061182
> --- /dev/null
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c
> @@ -0,0 +1,132 @@
[......]
> +module_platform_driver(sophgo_dwmac_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("Sophgo DWMAC platform driver");

Missing MODULE_AUTHOR ......
Inochi Amaoto Oct. 22, 2024, 10:21 a.m. UTC | #5
On Mon, Oct 21, 2024 at 03:27:18PM +0200, Andrew Lunn wrote:
> > It is related to the RGMII delay. On sg2044, when the phy 
> > sets rx-delay, the interal mac is not set the same delay, 
> > so this is needed to be set.
> 
> This is the wrong way to do it. Please look at how phy-mode should be
> used, the four different "rgmii" values. Nearly everybody gets this
> wrong, so there are plenty of emails from me in the netdev list about
> how it should be done.
> 

The phy-mode is alreay set to the "rgmii-id" and a rx delay is already
set (a default tx delay is set by the phy driver). In the scenario 
the extra bit is used to fix 2ns difference between the sampling clock
and data. It is more like an extra setting and the kernel can not handle
it by only setting the phy-mode.

This is draft dts patch for the sg2044 gmac.
https://github.com/project-inochi/linux/commit/381cb6000044a89cb13d6d9c839e9bbc7b9d2e5a

Regards,
Inochi
kernel test robot Oct. 22, 2024, 11:04 a.m. UTC | #6
Hi Inochi,

kernel test robot noticed the following build warnings:

[auto build test WARNING on robh/for-next]
[also build test WARNING on sophgo/for-next sophgo/fixes net-next/main net/main linus/master v6.12-rc4 next-20241021]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Inochi-Amaoto/dt-bindings-net-snps-dwmac-Add-dwmac-5-30a-version/20241021-184301
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20241021103617.653386-5-inochiama%40gmail.com
patch subject: [PATCH 4/4] net: stmmac: Add glue layer for Sophgo SG2044 SoC
config: x86_64-allyesconfig (https://download.01.org/0day-ci/archive/20241022/202410221853.0nt4WyvW-lkp@intel.com/config)
compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241022/202410221853.0nt4WyvW-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410221853.0nt4WyvW-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c:41:2: warning: variable 'rate' is used uninitialized whenever switch default is taken [-Wsometimes-uninitialized]
      41 |         default:
         |         ^~~~~~~
   drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c:46:36: note: uninitialized use occurs here
      46 |         ret = clk_set_rate(dwmac->clk_tx, rate);
         |                                           ^~~~
   drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c:28:20: note: initialize the variable 'rate' to silence this warning
      28 |         unsigned long rate;
         |                           ^
         |                            = 0
   1 warning generated.

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for MODVERSIONS
   Depends on [n]: MODULES [=y] && !COMPILE_TEST [=y]
   Selected by [y]:
   - RANDSTRUCT_FULL [=y] && (CC_HAS_RANDSTRUCT [=y] || GCC_PLUGINS [=n]) && MODULES [=y]


vim +/rate +41 drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c

    24	
    25	static void sophgo_dwmac_fix_mac_speed(void *priv, unsigned int speed, unsigned int mode)
    26	{
    27		struct sophgo_dwmac *dwmac = priv;
    28		unsigned long rate;
    29		int ret;
    30	
    31		switch (speed) {
    32		case SPEED_1000:
    33			rate = 125000000;
    34			break;
    35		case SPEED_100:
    36			rate = 25000000;
    37			break;
    38		case SPEED_10:
    39			rate = 2500000;
    40			break;
  > 41		default:
    42			dev_err(dwmac->dev, "invalid speed %u\n", speed);
    43			break;
    44		}
    45	
    46		ret = clk_set_rate(dwmac->clk_tx, rate);
    47		if (ret)
    48			dev_err(dwmac->dev, "failed to set tx rate %lu\n", rate);
    49	}
    50
Andrew Lunn Oct. 22, 2024, 1:51 p.m. UTC | #7
On Tue, Oct 22, 2024 at 06:21:49PM +0800, Inochi Amaoto wrote:
> On Mon, Oct 21, 2024 at 03:27:18PM +0200, Andrew Lunn wrote:
> > > It is related to the RGMII delay. On sg2044, when the phy 
> > > sets rx-delay, the interal mac is not set the same delay, 
> > > so this is needed to be set.
> > 
> > This is the wrong way to do it. Please look at how phy-mode should be
> > used, the four different "rgmii" values. Nearly everybody gets this
> > wrong, so there are plenty of emails from me in the netdev list about
> > how it should be done.
> > 
> 
> The phy-mode is alreay set to the "rgmii-id" and a rx delay is already
> set (a default tx delay is set by the phy driver). In the scenario 
> the extra bit is used to fix 2ns difference between the sampling clock
> and data. It is more like an extra setting and the kernel can not handle
> it by only setting the phy-mode.

This sounds wrong.

So in DT you have rgmii-id? You say the PHY is doing TX delay. So you
pass PHY_INTERFACE_MODE_RGMII_TXID to the PHY? It is not clear from
this patch, i don't see any code mentioning
PHY_INTERFACE_MODE_RGMII_TXID. Could you point me at that code.

	Andrew
diff mbox series

Patch

diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 05cc07b8f48c..bc44b21c593f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -169,6 +169,17 @@  config DWMAC_SOCFPGA
 	  for the stmmac device driver. This driver is used for
 	  arria5 and cyclone5 FPGA SoCs.
 
+config DWMAC_SOPHGO
+	tristate "Sophgo dwmac support"
+	depends on OF && (ARCH_SOPHGO || COMPILE_TEST)
+	default m if ARCH_SOPHGO
+	help
+	  Support for ethernet controllers on Sophgo RISC-V SoCs
+
+	  This selects the Sophgo SoC specific glue layer support
+	  for the stmmac device driver. This driver is used for the
+	  ethernet controllers on various Sophgo SoCs.
+
 config DWMAC_STARFIVE
 	tristate "StarFive dwmac support"
 	depends on OF && (ARCH_STARFIVE || COMPILE_TEST)
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index c2f0e91f6bf8..e1287b53047b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -23,6 +23,7 @@  obj-$(CONFIG_DWMAC_QCOM_ETHQOS)	+= dwmac-qcom-ethqos.o
 obj-$(CONFIG_DWMAC_ROCKCHIP)	+= dwmac-rk.o
 obj-$(CONFIG_DWMAC_RZN1)	+= dwmac-rzn1.o
 obj-$(CONFIG_DWMAC_SOCFPGA)	+= dwmac-altr-socfpga.o
+obj-$(CONFIG_DWMAC_SOPHGO)	+= dwmac-sophgo.o
 obj-$(CONFIG_DWMAC_STARFIVE)	+= dwmac-starfive.o
 obj-$(CONFIG_DWMAC_STI)		+= dwmac-sti.o
 obj-$(CONFIG_DWMAC_STM32)	+= dwmac-stm32.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c
new file mode 100644
index 000000000000..83c67c061182
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c
@@ -0,0 +1,132 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Sophgo DWMAC platform driver
+ *
+ * Copyright (C) 2024 Inochi Amaoto <inochiama@gmail.com>
+ *
+ */
+
+#include <linux/bits.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+
+#include "stmmac_platform.h"
+
+struct sophgo_dwmac {
+	struct device *dev;
+	struct clk *clk_tx;
+};
+
+#define DWMAC_SG2044_FLAG_USE_RX_DELAY		BIT(16)
+
+static void sophgo_dwmac_fix_mac_speed(void *priv, unsigned int speed, unsigned int mode)
+{
+	struct sophgo_dwmac *dwmac = priv;
+	unsigned long rate;
+	int ret;
+
+	switch (speed) {
+	case SPEED_1000:
+		rate = 125000000;
+		break;
+	case SPEED_100:
+		rate = 25000000;
+		break;
+	case SPEED_10:
+		rate = 2500000;
+		break;
+	default:
+		dev_err(dwmac->dev, "invalid speed %u\n", speed);
+		break;
+	}
+
+	ret = clk_set_rate(dwmac->clk_tx, rate);
+	if (ret)
+		dev_err(dwmac->dev, "failed to set tx rate %lu\n", rate);
+}
+
+static int sophgo_sg2044_dwmac_init(struct platform_device *pdev,
+				    struct plat_stmmacenet_data *plat_dat,
+				    struct stmmac_resources *stmmac_res)
+{
+	struct sophgo_dwmac *dwmac;
+	struct regmap *regmap;
+	unsigned int args[2];
+	int ret;
+
+	dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
+	if (!dwmac)
+		return -ENOMEM;
+
+	dwmac->clk_tx = devm_clk_get_enabled(&pdev->dev, "tx");
+	if (IS_ERR(dwmac->clk_tx))
+		return dev_err_probe(&pdev->dev, PTR_ERR(dwmac->clk_tx),
+				     "failed to get tx clock\n");
+
+	regmap = syscon_regmap_lookup_by_phandle_args(pdev->dev.of_node,
+						      "sophgo,syscon",
+						      2, args);
+	if (IS_ERR(regmap))
+		return dev_err_probe(&pdev->dev, PTR_ERR(regmap),
+				     "failed to get the regmap\n");
+
+	ret = regmap_set_bits(regmap, args[0], DWMAC_SG2044_FLAG_USE_RX_DELAY);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to set the phy rx delay\n");
+
+	dwmac->dev = &pdev->dev;
+	plat_dat->bsp_priv = dwmac;
+	plat_dat->flags |= STMMAC_FLAG_SPH_DISABLE;
+	plat_dat->fix_mac_speed = sophgo_dwmac_fix_mac_speed;
+	plat_dat->multicast_filter_bins = 0;
+	plat_dat->unicast_filter_entries = 1;
+
+	return 0;
+}
+
+static int sophgo_dwmac_probe(struct platform_device *pdev)
+{
+	struct plat_stmmacenet_data *plat_dat;
+	struct stmmac_resources stmmac_res;
+	int ret;
+
+	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to get resources\n");
+
+	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
+	if (IS_ERR(plat_dat))
+		return dev_err_probe(&pdev->dev, PTR_ERR(plat_dat),
+				     "dt configuration failed\n");
+
+	ret = sophgo_sg2044_dwmac_init(pdev, plat_dat, &stmmac_res);
+	if (ret)
+		return ret;
+
+	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+}
+
+static const struct of_device_id sophgo_dwmac_match[] = {
+	{ .compatible = "sophgo,sg2044-dwmac" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sophgo_dwmac_match);
+
+static struct platform_driver sophgo_dwmac_driver = {
+	.probe  = sophgo_dwmac_probe,
+	.remove_new = stmmac_pltfr_remove,
+	.driver = {
+		.name = "sophgo-dwmac",
+		.pm = &stmmac_pltfr_pm_ops,
+		.of_match_table = sophgo_dwmac_match,
+	},
+};
+module_platform_driver(sophgo_dwmac_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Sophgo DWMAC platform driver");