diff options
Diffstat (limited to 'drivers/net/dwc_eth_qos.c')
-rw-r--r-- | drivers/net/dwc_eth_qos.c | 83 |
1 files changed, 75 insertions, 8 deletions
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 43f0ec7637d..3415c418a93 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -32,6 +32,7 @@ #include <clk.h> #include <cpu_func.h> #include <dm.h> +#include <dm/device_compat.h> #include <errno.h> #include <eth_phy.h> #include <log.h> @@ -1301,6 +1302,13 @@ static int eqos_probe_resources_tegra186(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); + ret = eqos_get_base_addr_dt(dev); + if (ret) { + pr_err("eqos_get_base_addr_dt failed: %d\n", ret); + return ret; + } + eqos->tegra186_regs = (void *)(eqos->regs + EQOS_TEGRA186_REGS_BASE); + ret = reset_get_by_name(dev, "eqos", &eqos->reset_ctl); if (ret) { pr_err("reset_get_by_name(rst) failed: %d\n", ret); @@ -1375,6 +1383,69 @@ static int eqos_remove_resources_tegra186(struct udevice *dev) return 0; } +static int eqos_bind(struct udevice *dev) +{ + static int dev_num; + const size_t name_sz = 16; + char name[name_sz]; + + /* Device name defaults to DT node name. */ + if (ofnode_valid(dev_ofnode(dev))) + return 0; + + /* Assign unique names in case there is no DT node. */ + snprintf(name, name_sz, "eth_eqos#%d", dev_num++); + return device_set_name(dev, name); +} + +/* + * Get driver data based on the device tree. Boards not using a device tree can + * overwrite this function. + */ +__weak void *eqos_get_driver_data(struct udevice *dev) +{ + return (void *)dev_get_driver_data(dev); +} + +static fdt_addr_t eqos_get_base_addr_common(struct udevice *dev, fdt_addr_t addr) +{ + struct eqos_priv *eqos = dev_get_priv(dev); + + if (addr == FDT_ADDR_T_NONE) { +#if CONFIG_IS_ENABLED(FDT_64BIT) + dev_err(dev, "addr=0x%llx is invalid.\n", addr); +#else + dev_err(dev, "addr=0x%x is invalid.\n", addr); +#endif + return -EINVAL; + } + + eqos->regs = addr; + eqos->mac_regs = (void *)(addr + EQOS_MAC_REGS_BASE); + eqos->mtl_regs = (void *)(addr + EQOS_MTL_REGS_BASE); + eqos->dma_regs = (void *)(addr + EQOS_DMA_REGS_BASE); + + return 0; +} + +int eqos_get_base_addr_dt(struct udevice *dev) +{ + fdt_addr_t addr = dev_read_addr(dev); + return eqos_get_base_addr_common(dev, addr); +} + +int eqos_get_base_addr_pci(struct udevice *dev) +{ + fdt_addr_t addr; + void *paddr; + + paddr = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_TYPE, + PCI_REGION_MEM); + addr = paddr ? (fdt_addr_t)paddr : FDT_ADDR_T_NONE; + + return eqos_get_base_addr_common(dev, addr); +} + static int eqos_probe(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -1383,17 +1454,12 @@ static int eqos_probe(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); eqos->dev = dev; - eqos->config = (void *)dev_get_driver_data(dev); - eqos->regs = dev_read_addr(dev); - if (eqos->regs == FDT_ADDR_T_NONE) { - pr_err("dev_read_addr() failed\n"); + eqos->config = eqos_get_driver_data(dev); + if (!eqos->config) { + pr_err("Failed to get driver data.\n"); return -ENODEV; } - eqos->mac_regs = (void *)(eqos->regs + EQOS_MAC_REGS_BASE); - eqos->mtl_regs = (void *)(eqos->regs + EQOS_MTL_REGS_BASE); - eqos->dma_regs = (void *)(eqos->regs + EQOS_DMA_REGS_BASE); - eqos->tegra186_regs = (void *)(eqos->regs + EQOS_TEGRA186_REGS_BASE); eqos->max_speed = dev_read_u32_default(dev, "max-speed", 0); @@ -1574,6 +1640,7 @@ U_BOOT_DRIVER(eth_eqos) = { .name = "eth_eqos", .id = UCLASS_ETH, .of_match = of_match_ptr(eqos_ids), + .bind = eqos_bind, .probe = eqos_probe, .remove = eqos_remove, .ops = &eqos_ops, |