aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2023-08-15 21:49:34 -0400
committerTom Rini <trini@konsulko.com>2023-08-15 21:49:34 -0400
commit5d3758178bc23d731897f05244bf564f8d1caf48 (patch)
treeb58f6ace5d79245defdbce86cc58591552251e13
parentbdc682437a67b47a382edfa30f58f8271b8acfed (diff)
parent9a07d2df7647284d8d40976bf898b0856cbea9b1 (diff)
downloadu-boot-5d3758178bc23d731897f05244bf564f8d1caf48.zip
u-boot-5d3758178bc23d731897f05244bf564f8d1caf48.tar.gz
u-boot-5d3758178bc23d731897f05244bf564f8d1caf48.tar.bz2
Merge branch '2023-08-15-add-SGMII-support-for-TI-j7200' into next
To quote the author: 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.
-rw-r--r--configs/j7200_evm_a72_defconfig2
-rw-r--r--drivers/dma/ti/k3-psil-j721e.c17
-rw-r--r--drivers/net/ti/am65-cpsw-nuss.c61
-rw-r--r--drivers/phy/ti/phy-j721e-wiz.c21
4 files changed, 91 insertions, 10 deletions
diff --git a/configs/j7200_evm_a72_defconfig b/configs/j7200_evm_a72_defconfig
index ad8492a..ba5914d 100644
--- a/configs/j7200_evm_a72_defconfig
+++ b/configs/j7200_evm_a72_defconfig
@@ -114,6 +114,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
@@ -146,6 +147,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
diff --git a/drivers/dma/ti/k3-psil-j721e.c b/drivers/dma/ti/k3-psil-j721e.c
index 105ffd9..8e57e86 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 = {
diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c
index 51a8167..f4e5809 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>
@@ -26,6 +27,7 @@
#include <soc.h>
#include <syscon.h>
#include <linux/bitops.h>
+#include <linux/delay.h>
#include <linux/soc/ti/ti-udma.h>
#include "cpsw_mdio.h"
@@ -57,6 +59,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)
@@ -90,8 +98,11 @@
#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;
fdt_addr_t macsl_base;
bool disabled;
u32 mac_control;
@@ -113,6 +124,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;
@@ -204,6 +219,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)
@@ -229,6 +246,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)
@@ -280,6 +298,10 @@ static int 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(dev,
"Unsupported PHY mode: %u. Defaulting to MII.\n",
@@ -420,6 +442,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");
@@ -658,6 +687,16 @@ static int am65_cpsw_mdio_init(struct udevice *dev)
if (!priv->has_phy || cpsw_common->bus)
return 0;
+ if (IS_ENABLED(CONFIG_DM_GPIO)) {
+ 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);
+ }
+ }
+
ret = am65_cpsw_mdio_setup(dev);
if (ret)
return ret;
@@ -797,7 +836,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;
@@ -824,6 +863,24 @@ 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;
+ if (IS_ENABLED(CONFIG_DM_GPIO)) {
+ /* 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;
@@ -872,6 +929,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 +
+ (i * AM65_CPSW_SGMII_BASE);
port->macsl_base = port->port_base +
AM65_CPSW_CPSW_NU_PORT_MACSL_OFFSET;
}
diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
index 34314d0..7261339 100644
--- a/drivers/phy/ti/phy-j721e-wiz.c
+++ b/drivers/phy/ti/phy-j721e-wiz.c
@@ -585,12 +585,20 @@ 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)
- return 0;
-
- if (wiz->lane_phy_type[lane] == PHY_TYPE_PCIE)
- return regmap_field_write(wiz->p0_fullrt_div[lane], 0x1);
+ 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_16G:
+ 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;
+ }
return 0;
}
@@ -706,7 +714,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;