[PATCH 0/6] Add SGMII support for MAIN CPSW on TI's J7200 SoC

Hello,
This series adds support for SGMII mode to the CPSW driver to enable the functionality on TI's J7200 SoC.
Supporting SGMII mode also requires changes to the WIZ driver which acts as a wrapper for the SerDes used by the CPSW MAC to transmit data to the Ethernet PHY daughtercard mounted on the I2C GPIO Expander 2 connector on the J7200 EVM.
Powering on and resetting the Ethernet PHY requires MDIO support which is added to the CPSW driver.
For supporting DMA transactions from the MAIN CPSW instance to the A72 Host on J7200 SoC, the corresponding PSI-L endpoint information is added for the J721E SoC, which is applicable to J7200 SoC as well.
The SGMII daughtercard used for testing SGMII mode has TI's DP83869 PHY. Thus, enable the config for DP83869 driver functionality. Also, enable GPIO HOG config.
**NOTE**: This series is based on top of commit: 0beb649053 MAINTAINERS: correct at91 tree link and depends on the following patch being merged as well: Link: https://patchwork.ozlabs.org/project/uboot/patch/20230614222853.574427-1-dan...
Regards, Siddharth.
Siddharth Vadapalli (4): net: ti: am65-cpsw-nuss: Add support for SGMII mode phy: ti: phy-j721e-wiz: Add SGMII support in wiz driver for J7200 phy: ti: j721e-wiz: Add SGMII support in WIZ driver for J721E configs: j7200_evm_a72: Enable configs for SGMII support with MAIN CPSW0
Suman Anna (2): dma: ti: Update J21E PSIL endpoint information for MAIN CPSW0 net: ti: am65-cpsw-nuss: Add logic to support MDIO reset
configs/j7200_evm_a72_defconfig | 2 ++ drivers/dma/ti/k3-psil-j721e.c | 17 ++++++++-- drivers/net/ti/am65-cpsw-nuss.c | 57 ++++++++++++++++++++++++++++++++- drivers/phy/ti/phy-j721e-wiz.c | 21 ++++++++---- 4 files changed, 87 insertions(+), 10 deletions(-)

From: Suman Anna s-anna@ti.com
The PSIL endpoint data for J721E currently covers only the MCU domain CPSW0 instance. Add the data for the MAIN domain CPSW0 as well to allow the MAIN domain Ethernet ports to be usable on any platform using J721E SoC.
Additionally, since J721E's PSIL endpoint data is applicable to J7200 SoC as well, the MAIN CPSW0 instance on J7200 will also be usable now.
Signed-off-by: Suman Anna s-anna@ti.com [s-vadapalli@ti.com: Update commit message indicating support for J7200] Signed-off-by: Siddharth Vadapalli s-vadapalli@ti.com --- drivers/dma/ti/k3-psil-j721e.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/dma/ti/k3-psil-j721e.c b/drivers/dma/ti/k3-psil-j721e.c index 105ffd946f..8e57e860f2 100644 --- a/drivers/dma/ti/k3-psil-j721e.c +++ b/drivers/dma/ti/k3-psil-j721e.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com + * Copyright (C) 2019-2023 Texas Instruments Incorporated - https://www.ti.com * Author: Peter Ujfalusi peter.ujfalusi@ti.com */
@@ -21,13 +21,15 @@
/* PSI-L source thread IDs, used for RX (DMA_DEV_TO_MEM) */ static struct psil_ep j721e_src_ep_map[] = { - /* CPSW0 */ + /* MCU_CPSW0 */ PSIL_ETHERNET(0x7000), + /* MAIN_CPSW0 */ + PSIL_ETHERNET(0x4a00), };
/* PSI-L destination thread IDs, used for TX (DMA_MEM_TO_DEV) */ static struct psil_ep j721e_dst_ep_map[] = { - /* CPSW0 */ + /* MCU_CPSW0 */ PSIL_ETHERNET(0xf000), PSIL_ETHERNET(0xf001), PSIL_ETHERNET(0xf002), @@ -36,6 +38,15 @@ static struct psil_ep j721e_dst_ep_map[] = { PSIL_ETHERNET(0xf005), PSIL_ETHERNET(0xf006), PSIL_ETHERNET(0xf007), + /* MAIN_CPSW0 */ + PSIL_ETHERNET(0xca00), + PSIL_ETHERNET(0xca01), + PSIL_ETHERNET(0xca02), + PSIL_ETHERNET(0xca03), + PSIL_ETHERNET(0xca04), + PSIL_ETHERNET(0xca05), + PSIL_ETHERNET(0xca06), + PSIL_ETHERNET(0xca07), };
struct psil_ep_map j721e_ep_map = {

Add support for configuring the CPSW Ethernet Switch in SGMII mode.
Signed-off-by: Siddharth Vadapalli s-vadapalli@ti.com --- drivers/net/ti/am65-cpsw-nuss.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c index 523a4c9f91..403de3ea25 100644 --- a/drivers/net/ti/am65-cpsw-nuss.c +++ b/drivers/net/ti/am65-cpsw-nuss.c @@ -54,6 +54,12 @@ #define AM65_CPSW_PN_REG_SA_L 0x308 #define AM65_CPSW_PN_REG_SA_H 0x30c
+#define AM65_CPSW_SGMII_CONTROL_REG 0x010 +#define AM65_CPSW_SGMII_MR_ADV_ABILITY_REG 0x018 +#define AM65_CPSW_SGMII_CONTROL_MR_AN_ENABLE BIT(0) + +#define ADVERTISE_SGMII 0x1 + #define AM65_CPSW_ALE_CTL_REG 0x8 #define AM65_CPSW_ALE_CTL_REG_ENABLE BIT(31) #define AM65_CPSW_ALE_CTL_REG_RESET_TBL BIT(30) @@ -89,6 +95,7 @@
struct am65_cpsw_port { fdt_addr_t port_base; + fdt_addr_t port_sgmii_base; fdt_addr_t macsl_base; bool disabled; u32 mac_control; @@ -203,6 +210,8 @@ static int am65_cpsw_update_link(struct am65_cpsw_priv *priv) mac_control |= AM65_CPSW_MACSL_CTL_REG_FULL_DUPLEX; if (phy->speed == 100) mac_control |= AM65_CPSW_MACSL_CTL_REG_IFCTL_A; + if (phy->interface == PHY_INTERFACE_MODE_SGMII) + mac_control |= AM65_CPSW_MACSL_CTL_EXT_EN; }
if (mac_control == port->mac_control) @@ -228,6 +237,7 @@ out: #define AM65_GMII_SEL_MODE_MII 0 #define AM65_GMII_SEL_MODE_RMII 1 #define AM65_GMII_SEL_MODE_RGMII 2 +#define AM65_GMII_SEL_MODE_SGMII 3
#define AM65_GMII_SEL_RGMII_IDMODE BIT(4)
@@ -260,6 +270,10 @@ static void am65_cpsw_gmii_sel_k3(struct am65_cpsw_priv *priv, rgmii_id = true; break;
+ case PHY_INTERFACE_MODE_SGMII: + mode = AM65_GMII_SEL_MODE_SGMII; + break; + default: dev_warn(common->dev, "Unsupported PHY mode: %u. Defaulting to MII.\n", @@ -396,6 +410,13 @@ static int am65_cpsw_start(struct udevice *dev) goto err_dis_rx; }
+ if (priv->phydev->interface == PHY_INTERFACE_MODE_SGMII) { + writel(ADVERTISE_SGMII, + port->port_sgmii_base + AM65_CPSW_SGMII_MR_ADV_ABILITY_REG); + writel(AM65_CPSW_SGMII_CONTROL_MR_AN_ENABLE, + port->port_sgmii_base + AM65_CPSW_SGMII_CONTROL_REG); + } + ret = phy_startup(priv->phydev); if (ret) { dev_err(dev, "phy_startup failed\n"); @@ -779,6 +800,8 @@ static int am65_cpsw_probe_nuss(struct udevice *dev) port->port_base = cpsw_common->cpsw_base + AM65_CPSW_CPSW_NU_PORTS_OFFSET + (i * AM65_CPSW_CPSW_NU_PORTS_OFFSET); + port->port_sgmii_base = cpsw_common->ss_base + + AM65_CPSW_SGMII_BASE * (i); port->macsl_base = port->port_base + AM65_CPSW_CPSW_NU_PORT_MACSL_OFFSET; }

From: Suman Anna s-anna@ti.com
Enhance the AM65 CPSW NUSS driver to perform a MDIO reset using a GPIO line. Logic is also added to perform a pre and post delay around reset using the optional 'reset-delay-us' and 'reset-post-delay-us' properties. This is similar to the reset being performed in the Linux kernel. The reset is done once when the CPSW MDIO bus is being initialized.
Signed-off-by: Suman Anna s-anna@ti.com Signed-off-by: Siddharth Vadapalli s-vadapalli@ti.com --- drivers/net/ti/am65-cpsw-nuss.c | 34 ++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c index 403de3ea25..f39d1adc99 100644 --- a/drivers/net/ti/am65-cpsw-nuss.c +++ b/drivers/net/ti/am65-cpsw-nuss.c @@ -9,6 +9,7 @@ #include <common.h> #include <malloc.h> #include <asm/cache.h> +#include <asm/gpio.h> #include <asm/io.h> #include <asm/processor.h> #include <clk.h> @@ -23,6 +24,7 @@ #include <power-domain.h> #include <soc.h> #include <linux/bitops.h> +#include <linux/delay.h> #include <linux/soc/ti/ti-udma.h>
#include "cpsw_mdio.h" @@ -93,6 +95,8 @@
#define AM65_CPSW_CPPI_PKT_TYPE 0x7
+#define DEFAULT_GPIO_RESET_DELAY 10 + struct am65_cpsw_port { fdt_addr_t port_base; fdt_addr_t port_sgmii_base; @@ -119,6 +123,10 @@ struct am65_cpsw_common { struct mii_dev *bus; u32 bus_freq;
+ struct gpio_desc mdio_gpio_reset; + u32 reset_delay_us; + u32 reset_post_delay_us; + struct dma dma_tx; struct dma dma_rx; u32 rx_next; @@ -590,6 +598,14 @@ static int am65_cpsw_mdio_init(struct udevice *dev) if (!priv->has_phy || cpsw_common->bus) return 0;
+ if (dm_gpio_is_valid(&cpsw_common->mdio_gpio_reset)) { + dm_gpio_set_value(&cpsw_common->mdio_gpio_reset, 1); + udelay(cpsw_common->reset_delay_us); + dm_gpio_set_value(&cpsw_common->mdio_gpio_reset, 0); + if (cpsw_common->reset_post_delay_us > 0) + udelay(cpsw_common->reset_post_delay_us); + } + cpsw_common->bus = cpsw_mdio_init(dev->name, cpsw_common->mdio_base, cpsw_common->bus_freq, @@ -723,7 +739,7 @@ out: static int am65_cpsw_probe_nuss(struct udevice *dev) { struct am65_cpsw_common *cpsw_common = dev_get_priv(dev); - ofnode ports_np, node; + ofnode ports_np, node, mdio_np; int ret, i; struct udevice *port_dev;
@@ -752,6 +768,22 @@ static int am65_cpsw_probe_nuss(struct udevice *dev) AM65_CPSW_CPSW_NU_ALE_BASE; cpsw_common->mdio_base = cpsw_common->ss_base + AM65_CPSW_MDIO_BASE;
+ /* get bus level PHY reset GPIO details */ + mdio_np = dev_read_subnode(dev, "mdio"); + if (!ofnode_valid(mdio_np)) { + ret = -ENOENT; + goto out; + } + + cpsw_common->reset_delay_us = ofnode_read_u32_default(mdio_np, "reset-delay-us", + DEFAULT_GPIO_RESET_DELAY); + cpsw_common->reset_post_delay_us = ofnode_read_u32_default(mdio_np, + "reset-post-delay-us", + 0); + ret = gpio_request_by_name_nodev(mdio_np, "reset-gpios", 0, + &cpsw_common->mdio_gpio_reset, + GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); + ports_np = dev_read_subnode(dev, "ethernet-ports"); if (!ofnode_valid(ports_np)) { ret = -ENOENT;

On Sat, Jul 08, 2023 at 04:15:20PM +0530, Siddharth Vadapalli wrote:
From: Suman Anna s-anna@ti.com
Enhance the AM65 CPSW NUSS driver to perform a MDIO reset using a GPIO line. Logic is also added to perform a pre and post delay around reset using the optional 'reset-delay-us' and 'reset-post-delay-us' properties. This is similar to the reset being performed in the Linux kernel. The reset is done once when the CPSW MDIO bus is being initialized.
Signed-off-by: Suman Anna s-anna@ti.com Signed-off-by: Siddharth Vadapalli s-vadapalli@ti.com
drivers/net/ti/am65-cpsw-nuss.c | 34 ++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-)
So this breaks building on am62x_evm_a53 because now TI_AM65_CPSW_NUSS needs to select DM_GPIO. And the next problem is that we don't enable a GPIO driver on that platform as we should I suspect make DA8XX_GPIO default y if K3.

Tom,
On 22/07/23 01:06, Tom Rini wrote:
On Sat, Jul 08, 2023 at 04:15:20PM +0530, Siddharth Vadapalli wrote:
From: Suman Anna s-anna@ti.com
Enhance the AM65 CPSW NUSS driver to perform a MDIO reset using a GPIO line. Logic is also added to perform a pre and post delay around reset using the optional 'reset-delay-us' and 'reset-post-delay-us' properties. This is similar to the reset being performed in the Linux kernel. The reset is done once when the CPSW MDIO bus is being initialized.
Signed-off-by: Suman Anna s-anna@ti.com Signed-off-by: Siddharth Vadapalli s-vadapalli@ti.com
drivers/net/ti/am65-cpsw-nuss.c | 34 ++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-)
So this breaks building on am62x_evm_a53 because now TI_AM65_CPSW_NUSS needs to select DM_GPIO. And the next problem is that we don't enable a GPIO driver on that platform as we should I suspect make DA8XX_GPIO default y if K3.
Sorry for the delayed response. I am planning to address this issue by using: #if CONFIG_IS_ENABLED(DM_GPIO) in the driver, similar to how it is done for other ethernet drivers such as: drivers/net/mvneta.c and drivers/net/mvpp2.c.
Also, the GPIO hog and reset capabilities are only required on those boards which have the Ethernet PHY present on a daughtercard connected to the board.
I will post the v2 of this series with the above changes to fix the build issues. Please let me know if the above approach is acceptable.

On 31/07/23 10:13, Siddharth Vadapalli wrote:
Tom,
On 22/07/23 01:06, Tom Rini wrote:
On Sat, Jul 08, 2023 at 04:15:20PM +0530, Siddharth Vadapalli wrote:
From: Suman Anna s-anna@ti.com
Enhance the AM65 CPSW NUSS driver to perform a MDIO reset using a GPIO line. Logic is also added to perform a pre and post delay around reset using the optional 'reset-delay-us' and 'reset-post-delay-us' properties. This is similar to the reset being performed in the Linux kernel. The reset is done once when the CPSW MDIO bus is being initialized.
Signed-off-by: Suman Anna s-anna@ti.com Signed-off-by: Siddharth Vadapalli s-vadapalli@ti.com
drivers/net/ti/am65-cpsw-nuss.c | 34 ++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-)
So this breaks building on am62x_evm_a53 because now TI_AM65_CPSW_NUSS needs to select DM_GPIO. And the next problem is that we don't enable a GPIO driver on that platform as we should I suspect make DA8XX_GPIO default y if K3.
Sorry for the delayed response. I am planning to address this issue by using: #if CONFIG_IS_ENABLED(DM_GPIO)
Instead of CONFIG_IS_ENABLED(DM_GPIO), I will use: if (IS_ENABLED(CONFIG_DM_GPIO)) { in the functions.
in the driver, similar to how it is done for other ethernet drivers such as: drivers/net/mvneta.c and drivers/net/mvpp2.c.
Also, the GPIO hog and reset capabilities are only required on those boards which have the Ethernet PHY present on a daughtercard connected to the board.
I will post the v2 of this series with the above changes to fix the build issues. Please let me know if the above approach is acceptable.

On Mon, Jul 31, 2023 at 02:06:26PM +0530, Siddharth Vadapalli wrote:
On 31/07/23 10:13, Siddharth Vadapalli wrote:
Tom,
On 22/07/23 01:06, Tom Rini wrote:
On Sat, Jul 08, 2023 at 04:15:20PM +0530, Siddharth Vadapalli wrote:
From: Suman Anna s-anna@ti.com
Enhance the AM65 CPSW NUSS driver to perform a MDIO reset using a GPIO line. Logic is also added to perform a pre and post delay around reset using the optional 'reset-delay-us' and 'reset-post-delay-us' properties. This is similar to the reset being performed in the Linux kernel. The reset is done once when the CPSW MDIO bus is being initialized.
Signed-off-by: Suman Anna s-anna@ti.com Signed-off-by: Siddharth Vadapalli s-vadapalli@ti.com
drivers/net/ti/am65-cpsw-nuss.c | 34 ++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-)
So this breaks building on am62x_evm_a53 because now TI_AM65_CPSW_NUSS needs to select DM_GPIO. And the next problem is that we don't enable a GPIO driver on that platform as we should I suspect make DA8XX_GPIO default y if K3.
Sorry for the delayed response. I am planning to address this issue by using: #if CONFIG_IS_ENABLED(DM_GPIO)
Instead of CONFIG_IS_ENABLED(DM_GPIO), I will use: if (IS_ENABLED(CONFIG_DM_GPIO)) { in the functions.
That will break SPL, if that's a use case on these platforms.
Please check that whatever approach you take doesn't break other platforms nor include code when not required on other platforms.

Select the same mac divider for SGMII too as the one being used for QSGMII.
Enable full rate divider configuration support for J721E_WIZ_10G for SGMII.
Signed-off-by: Siddharth Vadapalli s-vadapalli@ti.com --- drivers/phy/ti/phy-j721e-wiz.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c index 23397175d3..12421f90b0 100644 --- a/drivers/phy/ti/phy-j721e-wiz.c +++ b/drivers/phy/ti/phy-j721e-wiz.c @@ -575,12 +575,18 @@ static int wiz_reset_assert(struct reset_ctl *reset_ctl)
static int wiz_phy_fullrt_div(struct wiz *wiz, int lane) { - if (wiz->type != AM64_WIZ_10G) + switch (wiz->type) { + case AM64_WIZ_10G: + if (wiz->lane_phy_type[lane] == PHY_TYPE_PCIE) + return regmap_field_write(wiz->p0_fullrt_div[lane], 0x1); + break; + case J721E_WIZ_10G: + if (wiz->lane_phy_type[lane] == PHY_TYPE_SGMII) + return regmap_field_write(wiz->p0_fullrt_div[lane], 0x2); + break; + default: return 0; - - if (wiz->lane_phy_type[lane] == PHY_TYPE_PCIE) - return regmap_field_write(wiz->p0_fullrt_div[lane], 0x1); - + } return 0; }
@@ -696,7 +702,8 @@ static int wiz_p_mac_div_sel(struct wiz *wiz) int i;
for (i = 0; i < num_lanes; i++) { - if (wiz->lane_phy_type[i] == PHY_TYPE_QSGMII) { + if (wiz->lane_phy_type[i] == PHY_TYPE_SGMII || + wiz->lane_phy_type[i] == PHY_TYPE_QSGMII) { ret = regmap_field_write(wiz->p_mac_div_sel0[i], 1); if (ret) return ret;

Enable full rate divider configuration support for J721E_WIZ_16G for SGMII.
Signed-off-by: Siddharth Vadapalli s-vadapalli@ti.com --- drivers/phy/ti/phy-j721e-wiz.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c index 12421f90b0..ecb2f684ef 100644 --- a/drivers/phy/ti/phy-j721e-wiz.c +++ b/drivers/phy/ti/phy-j721e-wiz.c @@ -580,6 +580,8 @@ static int wiz_phy_fullrt_div(struct wiz *wiz, int lane) if (wiz->lane_phy_type[lane] == PHY_TYPE_PCIE) return regmap_field_write(wiz->p0_fullrt_div[lane], 0x1); break; + + case J721E_WIZ_16G: case J721E_WIZ_10G: if (wiz->lane_phy_type[lane] == PHY_TYPE_SGMII) return regmap_field_write(wiz->p0_fullrt_div[lane], 0x2);

The MAIN CPSW0 instance of CPSW Ethernet Switch on TI's J7200 SoC supports SGMII mode. To enable support for utilizing the SGMII daughtercard with TI's DP83869 PHY, enable the corresponding config.
Also, since the SGMII daughtercard is connected to the I2C GPIO Expander 2 connector on the J7200 EVM, powering on the Ethernet PHY and resetting it requires GPIO Hogging capability. Enable it as well.
Signed-off-by: Siddharth Vadapalli s-vadapalli@ti.com --- configs/j7200_evm_a72_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/j7200_evm_a72_defconfig b/configs/j7200_evm_a72_defconfig index e40900fffa..e5b5c85ed1 100644 --- a/configs/j7200_evm_a72_defconfig +++ b/configs/j7200_evm_a72_defconfig @@ -122,6 +122,7 @@ CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=0 CONFIG_FASTBOOT_CMD_OEM_FORMAT=y CONFIG_TI_SCI_PROTOCOL=y +CONFIG_GPIO_HOG=y CONFIG_DA8XX_GPIO=y CONFIG_DM_PCA953X=y CONFIG_DM_I2C=y @@ -154,6 +155,7 @@ CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI_FLASH_MTD=y CONFIG_MULTIPLEXER=y CONFIG_MUX_MMIO=y +CONFIG_PHY_TI_DP83869=y CONFIG_PHY_FIXED=y CONFIG_TI_AM65_CPSW_NUSS=y CONFIG_PHY=y
participants (2)
-
Siddharth Vadapalli
-
Tom Rini