net: am65-cpsw: cpsw_mdio: Switch to proper DM_MDIO framework
Add a new Kconfig symbol MDIO_TI_CPSW for the CPSW MDIO
driver and build it with proper DM support if enabled.
If MDIO_TI_CPSW is not enabled then we continue to
behave like before.
Clean up MDIO custom handling in am65-cpsw and use
dm_eth_phy_connect() to get the PHY.
Signed-off-by: Roger Quadros <rogerq@kernel.org>
Tested-by: Ravi Gunasekaran <r-gunasekaran@ti.com>
diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c
index 6da018c..d68ed67 100644
--- a/drivers/net/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ti/am65-cpsw-nuss.c
@@ -31,8 +31,6 @@
#include <linux/printk.h>
#include <linux/soc/ti/ti-udma.h>
-#include "cpsw_mdio.h"
-
#define AM65_CPSW_CPSWNU_MAX_PORTS 9
#define AM65_CPSW_SS_BASE 0x0
@@ -113,7 +111,6 @@
struct udevice *dev;
fdt_addr_t ss_base;
fdt_addr_t cpsw_base;
- fdt_addr_t mdio_base;
fdt_addr_t ale_base;
struct clk fclk;
@@ -122,13 +119,8 @@
u32 port_num;
struct am65_cpsw_port ports[AM65_CPSW_CPSWNU_MAX_PORTS];
- 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;
@@ -140,13 +132,7 @@
struct udevice *dev;
struct am65_cpsw_common *cpsw_common;
u32 port_id;
-
struct phy_device *phydev;
- bool has_phy;
- ofnode phy_node;
- u32 phy_addr;
-
- bool mdio_manual_mode;
};
#ifdef PKTSIZE_ALIGN
@@ -622,111 +608,15 @@
.read_rom_hwaddr = am65_cpsw_read_rom_hwaddr,
};
-static const struct soc_attr k3_mdio_soc_data[] = {
- { .family = "AM62X", .revision = "SR1.0" },
- { .family = "AM64X", .revision = "SR1.0" },
- { .family = "AM64X", .revision = "SR2.0" },
- { .family = "AM65X", .revision = "SR1.0" },
- { .family = "AM65X", .revision = "SR2.0" },
- { .family = "J7200", .revision = "SR1.0" },
- { .family = "J7200", .revision = "SR2.0" },
- { .family = "J721E", .revision = "SR1.0" },
- { .family = "J721E", .revision = "SR1.1" },
- { .family = "J721S2", .revision = "SR1.0" },
- { /* sentinel */ },
-};
-
-static ofnode am65_cpsw_find_mdio(ofnode parent)
-{
- ofnode node;
-
- ofnode_for_each_subnode(node, parent)
- if (ofnode_device_is_compatible(node, "ti,cpsw-mdio"))
- return node;
-
- return ofnode_null();
-}
-
-static int am65_cpsw_mdio_setup(struct udevice *dev)
-{
- struct am65_cpsw_priv *priv = dev_get_priv(dev);
- struct am65_cpsw_common *cpsw_common = priv->cpsw_common;
- struct udevice *mdio_dev;
- ofnode mdio;
- int ret;
-
- mdio = am65_cpsw_find_mdio(dev_ofnode(cpsw_common->dev));
- if (!ofnode_valid(mdio))
- return 0;
-
- /*
- * The MDIO controller is represented in the DT binding by a
- * subnode of the MAC controller.
- *
- * We don't have a DM driver for the MDIO device yet, and thus any
- * pinctrl setting on its node will be ignored.
- *
- * However, we do need to make sure the pins states tied to the
- * MDIO node are configured properly. Fortunately, the core DM
- * does that for use when we get a device, so we can work around
- * that whole issue by just requesting a dummy MDIO driver to
- * probe, and our pins will get muxed.
- */
- ret = uclass_get_device_by_ofnode(UCLASS_MDIO, mdio, &mdio_dev);
- if (ret)
- return ret;
-
- return 0;
-}
-
-static int am65_cpsw_mdio_init(struct udevice *dev)
-{
- struct am65_cpsw_priv *priv = dev_get_priv(dev);
- struct am65_cpsw_common *cpsw_common = priv->cpsw_common;
- int ret;
-
- 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;
-
- cpsw_common->bus = cpsw_mdio_init(dev->name,
- cpsw_common->mdio_base,
- cpsw_common->bus_freq,
- clk_get_rate(&cpsw_common->fclk),
- priv->mdio_manual_mode);
- if (!cpsw_common->bus)
- return -EFAULT;
-
- return 0;
-}
-
static int am65_cpsw_phy_init(struct udevice *dev)
{
struct am65_cpsw_priv *priv = dev_get_priv(dev);
- struct am65_cpsw_common *cpsw_common = priv->cpsw_common;
struct eth_pdata *pdata = dev_get_plat(dev);
struct phy_device *phydev;
u32 supported = PHY_GBIT_FEATURES;
int ret;
- phydev = phy_connect(cpsw_common->bus,
- priv->phy_addr,
- priv->dev,
- pdata->phy_interface);
-
+ phydev = dm_eth_phy_connect(dev);
if (!phydev) {
dev_err(dev, "phy_connect() failed\n");
return -ENODEV;
@@ -740,13 +630,10 @@
}
phydev->advertising = phydev->supported;
- if (ofnode_valid(priv->phy_node))
- phydev->node = priv->phy_node;
-
priv->phydev = phydev;
ret = phy_config(phydev);
if (ret < 0)
- pr_err("phy_config() failed: %d", ret);
+ dev_err(dev, "phy_config() failed: %d", ret);
return ret;
}
@@ -755,8 +642,6 @@
{
struct eth_pdata *pdata = dev_get_plat(dev);
struct am65_cpsw_priv *priv = dev_get_priv(dev);
- struct ofnode_phandle_args out_args;
- int ret = 0;
dev_read_u32(dev, "reg", &priv->port_id);
@@ -771,28 +656,7 @@
dev_err(dev, "Port %u speed froced to %uMbit\n",
priv->port_id, pdata->max_speed);
- priv->has_phy = true;
- ret = ofnode_parse_phandle_with_args(dev_ofnode(dev), "phy-handle",
- NULL, 0, 0, &out_args);
- if (ret) {
- dev_err(dev, "can't parse phy-handle port %u (%d)\n",
- priv->port_id, ret);
- priv->has_phy = false;
- ret = 0;
- }
-
- priv->phy_node = out_args.node;
- if (priv->has_phy) {
- ret = ofnode_read_u32(priv->phy_node, "reg", &priv->phy_addr);
- if (ret) {
- dev_err(dev, "failed to get phy_addr port %u (%d)\n",
- priv->port_id, ret);
- goto out;
- }
- }
-
-out:
- return ret;
+ return 0;
}
static int am65_cpsw_port_probe(struct udevice *dev)
@@ -811,10 +675,6 @@
sprintf(portname, "%s%s", dev->parent->name, dev->name);
device_set_name(dev, portname);
- priv->mdio_manual_mode = false;
- if (soc_device_match(k3_mdio_soc_data))
- priv->mdio_manual_mode = true;
-
ret = am65_cpsw_ofdata_parse_phy(dev);
if (ret)
goto out;
@@ -823,13 +683,8 @@
if (ret)
goto out;
- ret = am65_cpsw_mdio_init(dev);
- if (ret)
- goto out;
-
ret = am65_cpsw_phy_init(dev);
- if (ret)
- goto out;
+
out:
return ret;
}
@@ -837,7 +692,7 @@
static int am65_cpsw_probe_nuss(struct udevice *dev)
{
struct am65_cpsw_common *cpsw_common = dev_get_priv(dev);
- ofnode ports_np, node, mdio_np;
+ ofnode ports_np, node;
int ret, i;
struct udevice *port_dev;
@@ -862,25 +717,6 @@
cpsw_common->cpsw_base = cpsw_common->ss_base + AM65_CPSW_CPSW_NU_BASE;
cpsw_common->ale_base = cpsw_common->cpsw_base +
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)) {
@@ -940,12 +776,11 @@
dev_read_u32_default(dev, "bus_freq",
AM65_CPSW_MDIO_BUS_FREQ_DEF);
- dev_info(dev, "K3 CPSW: nuss_ver: 0x%08X cpsw_ver: 0x%08X ale_ver: 0x%08X Ports:%u mdio_freq:%u\n",
+ dev_info(dev, "K3 CPSW: nuss_ver: 0x%08X cpsw_ver: 0x%08X ale_ver: 0x%08X Ports:%u\n",
readl(cpsw_common->ss_base),
readl(cpsw_common->cpsw_base),
readl(cpsw_common->ale_base),
- cpsw_common->port_num,
- cpsw_common->bus_freq);
+ cpsw_common->port_num);
out:
power_domain_free(&cpsw_common->pwrdmn);
@@ -976,14 +811,3 @@
.plat_auto = sizeof(struct eth_pdata),
.flags = DM_FLAG_ALLOC_PRIV_DMA | DM_FLAG_OS_PREPARE,
};
-
-static const struct udevice_id am65_cpsw_mdio_ids[] = {
- { .compatible = "ti,cpsw-mdio" },
- { }
-};
-
-U_BOOT_DRIVER(am65_cpsw_mdio) = {
- .name = "am65_cpsw_mdio",
- .id = UCLASS_MDIO,
- .of_match = am65_cpsw_mdio_ids,
-};