/*
* Copyright (C) 2005-2006 Atmel Corporation
*/
-#include <common.h>
#include <clk.h>
#include <cpu_func.h>
#include <dm.h>
#include <log.h>
+#include <asm/global_data.h>
#include <linux/delay.h>
/*
*/
#include <net.h>
-#ifndef CONFIG_DM_ETH
-#include <netdev.h>
-#endif
#include <malloc.h>
#include <miiphy.h>
#define MACB_RX_DMA_DESC_SIZE (DMA_DESC_BYTES(MACB_RX_RING_SIZE))
#define MACB_TX_DUMMY_DMA_DESC_SIZE (DMA_DESC_BYTES(1))
+#define DESC_PER_CACHELINE_32 (ARCH_DMA_MINALIGN/sizeof(struct macb_dma_desc))
+#define DESC_PER_CACHELINE_64 (ARCH_DMA_MINALIGN/DMA_DESC_SIZE)
+
#define RXBUF_FRMLEN_MASK 0x00000fff
#define TXBUF_FRMLEN_MASK 0x000007ff
unsigned long dummy_desc_dma;
const struct device *dev;
-#ifndef CONFIG_DM_ETH
- struct eth_device netdev;
-#endif
+ unsigned int duplex;
+ unsigned int speed;
unsigned short phy_addr;
struct mii_dev *bus;
#ifdef CONFIG_PHYLIB
struct phy_device *phydev;
#endif
-#ifdef CONFIG_DM_ETH
#ifdef CONFIG_CLK
unsigned long pclk_rate;
#endif
phy_interface_t phy_interface;
-#endif
+};
+
+struct macb_usrio_cfg {
+ unsigned int mii;
+ unsigned int rmii;
+ unsigned int rgmii;
+ unsigned int clken;
};
struct macb_config {
unsigned int dma_burst_length;
unsigned int hw_dma_cap;
+ unsigned int caps;
int (*clk_init)(struct udevice *dev, ulong rate);
+ const struct macb_usrio_cfg *usrio;
};
-#ifndef CONFIG_DM_ETH
-#define to_macb(_nd) container_of(_nd, struct macb_device, netdev)
-#endif
-
static int macb_is_gem(struct macb_device *macb)
{
return MACB_BFEXT(IDNUM, macb_readl(macb, MID)) >= 0x2;
return macb_is_gem(macb) && !cpu_is_sama5d2() && !cpu_is_sama5d4();
}
+/* Is the port a fixed link */
+static int macb_port_is_fixed_link(struct macb_device *macb)
+{
+ return macb->phy_addr > PHY_MAX_ADDR;
+}
+
static void macb_mdio_write(struct macb_device *macb, u8 phy_adr, u8 reg,
u16 value)
{
int macb_miiphy_read(struct mii_dev *bus, int phy_adr, int devad, int reg)
{
u16 value = 0;
-#ifdef CONFIG_DM_ETH
struct udevice *dev = eth_get_dev_by_name(bus->name);
struct macb_device *macb = dev_get_priv(dev);
-#else
- struct eth_device *dev = eth_get_dev_by_name(bus->name);
- struct macb_device *macb = to_macb(dev);
-#endif
arch_get_mdio_control(bus->name);
value = macb_mdio_read(macb, phy_adr, reg);
int macb_miiphy_write(struct mii_dev *bus, int phy_adr, int devad, int reg,
u16 value)
{
-#ifdef CONFIG_DM_ETH
struct udevice *dev = eth_get_dev_by_name(bus->name);
struct macb_device *macb = dev_get_priv(dev);
-#else
- struct eth_device *dev = eth_get_dev_by_name(bus->name);
- struct macb_device *macb = to_macb(dev);
-#endif
arch_get_mdio_control(bus->name);
macb_mdio_write(macb, phy_adr, reg, value);
return 0;
}
+static void reclaim_rx_buffer(struct macb_device *macb,
+ unsigned int idx)
+{
+ unsigned int mask;
+ unsigned int shift;
+ unsigned int i;
+
+ /*
+ * There may be multiple descriptors per CPU cacheline,
+ * so a cache flush would flush the whole line, meaning the content of other descriptors
+ * in the cacheline would also flush. If one of the other descriptors had been
+ * written to by the controller, the flush would cause those changes to be lost.
+ *
+ * To circumvent this issue, we do the actual freeing only when we need to free
+ * the last descriptor in the current cacheline. When the current descriptor is the
+ * last in the cacheline, we free all the descriptors that belong to that cacheline.
+ */
+ if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) {
+ mask = DESC_PER_CACHELINE_64 - 1;
+ shift = 1;
+ } else {
+ mask = DESC_PER_CACHELINE_32 - 1;
+ shift = 0;
+ }
+
+ /* we exit without freeing if idx is not the last descriptor in the cacheline */
+ if ((idx & mask) != mask)
+ return;
+
+ for (i = idx & (~mask); i <= idx; i++)
+ macb->rx_ring[i << shift].addr &= ~MACB_BIT(RX_USED);
+}
+
static void reclaim_rx_buffers(struct macb_device *macb,
unsigned int new_tail)
{
unsigned int i;
- unsigned int count;
i = macb->rx_tail;
macb_invalidate_ring_desc(macb, RX);
while (i > new_tail) {
- if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
- count = i * 2;
- else
- count = i;
- macb->rx_ring[count].addr &= ~MACB_BIT(RX_USED);
+ reclaim_rx_buffer(macb, i);
i++;
- if (i > MACB_RX_RING_SIZE)
+ if (i >= MACB_RX_RING_SIZE)
i = 0;
}
while (i < new_tail) {
- if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
- count = i * 2;
- else
- count = i;
- macb->rx_ring[count].addr &= ~MACB_BIT(RX_USED);
+ reclaim_rx_buffer(macb, i);
i++;
}
* Returns 0 when operation success and negative errno number
* when operation failed.
*/
-#ifdef CONFIG_DM_ETH
static int macb_sifive_clk_init(struct udevice *dev, ulong rate)
{
- fdt_addr_t addr;
void *gemgxl_regs;
- addr = dev_read_addr_index(dev, 1);
- if (addr == FDT_ADDR_T_NONE)
- return -ENODEV;
-
- gemgxl_regs = (void __iomem *)addr;
+ gemgxl_regs = dev_read_addr_index_ptr(dev, 1);
if (!gemgxl_regs)
return -ENODEV;
return 0;
}
+static int macb_sama7g5_clk_init(struct udevice *dev, ulong rate)
+{
+ struct clk clk;
+ int ret;
+
+ ret = clk_get_by_name(dev, "tx_clk", &clk);
+ if (ret)
+ return ret;
+
+ /*
+ * This is for using GCK. Clock rate is addressed via assigned-clock
+ * property, so only clock enable is needed here. The switching to
+ * proper clock rate depending on link speed is managed by IP logic.
+ */
+ return clk_enable(&clk);
+}
+
int __weak macb_linkspd_cb(struct udevice *dev, unsigned int speed)
{
#ifdef CONFIG_CLK
if (tx_clk.dev) {
ret = clk_set_rate(&tx_clk, rate);
- if (ret)
+ if (ret < 0)
return ret;
}
#endif
return 0;
}
-#else
-int __weak macb_linkspd_cb(void *regs, unsigned int speed)
-{
- return 0;
-}
-#endif
-#ifdef CONFIG_DM_ETH
static int macb_phy_init(struct udevice *dev, const char *name)
-#else
-static int macb_phy_init(struct macb_device *macb, const char *name)
-#endif
{
-#ifdef CONFIG_DM_ETH
struct macb_device *macb = dev_get_priv(dev);
-#endif
u32 ncfgr;
u16 phy_id, status, adv, lpa;
int media, speed, duplex;
int i;
arch_get_mdio_control(name);
- /* Auto-detect phy_addr */
- ret = macb_phy_find(macb, name);
- if (ret)
- return ret;
+ /* If port is not fixed -> setup PHY */
+ if (!macb_port_is_fixed_link(macb)) {
+ /* Auto-detect phy_addr */
+ ret = macb_phy_find(macb, name);
+ if (ret)
+ return ret;
- /* Check if the PHY is up to snuff... */
- phy_id = macb_mdio_read(macb, macb->phy_addr, MII_PHYSID1);
- if (phy_id == 0xffff) {
- printf("%s: No PHY present\n", name);
- return -ENODEV;
- }
+ /* Check if the PHY is up to snuff... */
+ phy_id = macb_mdio_read(macb, macb->phy_addr, MII_PHYSID1);
+ if (phy_id == 0xffff) {
+ printf("%s: No PHY present\n", name);
+ return -ENODEV;
+ }
#ifdef CONFIG_PHYLIB
-#ifdef CONFIG_DM_ETH
- macb->phydev = phy_connect(macb->bus, macb->phy_addr, dev,
- macb->phy_interface);
-#else
- /* need to consider other phy interface mode */
- macb->phydev = phy_connect(macb->bus, macb->phy_addr, &macb->netdev,
- PHY_INTERFACE_MODE_RGMII);
-#endif
- if (!macb->phydev) {
- printf("phy_connect failed\n");
- return -ENODEV;
- }
+ macb->phydev = phy_connect(macb->bus, macb->phy_addr, dev,
+ macb->phy_interface);
+ if (!macb->phydev) {
+ printf("phy_connect failed\n");
+ return -ENODEV;
+ }
- phy_config(macb->phydev);
+ phy_config(macb->phydev);
#endif
- status = macb_mdio_read(macb, macb->phy_addr, MII_BMSR);
- if (!(status & BMSR_LSTATUS)) {
- /* Try to re-negotiate if we don't have link already. */
- macb_phy_reset(macb, name);
-
- for (i = 0; i < MACB_AUTONEG_TIMEOUT / 100; i++) {
- status = macb_mdio_read(macb, macb->phy_addr, MII_BMSR);
- if (status & BMSR_LSTATUS) {
- /*
- * Delay a bit after the link is established,
- * so that the next xfer does not fail
- */
- mdelay(10);
- break;
+ status = macb_mdio_read(macb, macb->phy_addr, MII_BMSR);
+ if (!(status & BMSR_LSTATUS)) {
+ /* Try to re-negotiate if we don't have link already. */
+ macb_phy_reset(macb, name);
+
+ for (i = 0; i < MACB_AUTONEG_TIMEOUT / 100; i++) {
+ status = macb_mdio_read(macb, macb->phy_addr, MII_BMSR);
+ if (status & BMSR_LSTATUS) {
+ /*
+ * Delay a bit after the link is established,
+ * so that the next xfer does not fail
+ */
+ mdelay(10);
+ break;
+ }
+ udelay(100);
}
- udelay(100);
}
- }
- if (!(status & BMSR_LSTATUS)) {
- printf("%s: link down (status: 0x%04x)\n",
- name, status);
- return -ENETDOWN;
- }
+ if (!(status & BMSR_LSTATUS)) {
+ printf("%s: link down (status: 0x%04x)\n",
+ name, status);
+ return -ENETDOWN;
+ }
- /* First check for GMAC and that it is GiB capable */
- if (gem_is_gigabit_capable(macb)) {
- lpa = macb_mdio_read(macb, macb->phy_addr, MII_STAT1000);
+ /* First check for GMAC and that it is GiB capable */
+ if (gem_is_gigabit_capable(macb)) {
+ lpa = macb_mdio_read(macb, macb->phy_addr, MII_STAT1000);
- if (lpa & (LPA_1000FULL | LPA_1000HALF | LPA_1000XFULL |
- LPA_1000XHALF)) {
- duplex = ((lpa & (LPA_1000FULL | LPA_1000XFULL)) ?
- 1 : 0);
+ if (lpa & (LPA_1000FULL | LPA_1000HALF | LPA_1000XFULL |
+ LPA_1000XHALF)) {
+ duplex = ((lpa & (LPA_1000FULL | LPA_1000XFULL)) ?
+ 1 : 0);
- printf("%s: link up, 1000Mbps %s-duplex (lpa: 0x%04x)\n",
- name,
- duplex ? "full" : "half",
- lpa);
+ printf("%s: link up, 1000Mbps %s-duplex (lpa: 0x%04x)\n",
+ name,
+ duplex ? "full" : "half",
+ lpa);
- ncfgr = macb_readl(macb, NCFGR);
- ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
- ncfgr |= GEM_BIT(GBE);
+ ncfgr = macb_readl(macb, NCFGR);
+ ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
+ ncfgr |= GEM_BIT(GBE);
- if (duplex)
- ncfgr |= MACB_BIT(FD);
+ if (duplex)
+ ncfgr |= MACB_BIT(FD);
- macb_writel(macb, NCFGR, ncfgr);
+ macb_writel(macb, NCFGR, ncfgr);
-#ifdef CONFIG_DM_ETH
- ret = macb_linkspd_cb(dev, _1000BASET);
-#else
- ret = macb_linkspd_cb(macb->regs, _1000BASET);
-#endif
- if (ret)
- return ret;
+ ret = macb_linkspd_cb(dev, _1000BASET);
+ if (ret)
+ return ret;
- return 0;
+ return 0;
+ }
}
- }
- /* fall back for EMAC checking */
- adv = macb_mdio_read(macb, macb->phy_addr, MII_ADVERTISE);
- lpa = macb_mdio_read(macb, macb->phy_addr, MII_LPA);
- media = mii_nway_result(lpa & adv);
- speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
- ? 1 : 0);
- duplex = (media & ADVERTISE_FULL) ? 1 : 0;
- printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n",
- name,
- speed ? "100" : "10",
- duplex ? "full" : "half",
- lpa);
+ /* fall back for EMAC checking */
+ adv = macb_mdio_read(macb, macb->phy_addr, MII_ADVERTISE);
+ lpa = macb_mdio_read(macb, macb->phy_addr, MII_LPA);
+ media = mii_nway_result(lpa & adv);
+ speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
+ ? 1 : 0);
+ duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+ printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n",
+ name,
+ speed ? "100" : "10",
+ duplex ? "full" : "half",
+ lpa);
+ } else {
+ /* if macb port is a fixed link */
+ /* TODO : manage gigabit capable processors */
+ speed = macb->speed;
+ duplex = macb->duplex;
+ printf("%s: link up, %sMbps %s-duplex\n",
+ name,
+ speed ? "100" : "10",
+ duplex ? "full" : "half");
+ }
ncfgr = macb_readl(macb, NCFGR);
ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD) | GEM_BIT(GBE));
if (speed) {
ncfgr |= MACB_BIT(SPD);
-#ifdef CONFIG_DM_ETH
ret = macb_linkspd_cb(dev, _100BASET);
-#else
- ret = macb_linkspd_cb(macb->regs, _100BASET);
-#endif
} else {
-#ifdef CONFIG_DM_ETH
ret = macb_linkspd_cb(dev, _10BASET);
-#else
- ret = macb_linkspd_cb(macb->regs, _10BASET);
-#endif
}
if (ret)
gem_writel(macb, DMACFG, dmacfg);
}
-#ifdef CONFIG_DM_ETH
static int _macb_init(struct udevice *dev, const char *name)
-#else
-static int _macb_init(struct macb_device *macb, const char *name)
-#endif
{
-#ifdef CONFIG_DM_ETH
struct macb_device *macb = dev_get_priv(dev);
-#endif
+ unsigned int val = 0;
unsigned long paddr;
int ret;
int i;
* When the GMAC IP without GE feature, this bit is used
* to select interface between RMII and MII.
*/
-#ifdef CONFIG_DM_ETH
- if ((macb->phy_interface == PHY_INTERFACE_MODE_RMII) ||
- (macb->phy_interface == PHY_INTERFACE_MODE_RGMII))
- gem_writel(macb, USRIO, GEM_BIT(RGMII));
- else
- gem_writel(macb, USRIO, 0);
+ if (macb->phy_interface == PHY_INTERFACE_MODE_RGMII ||
+ macb->phy_interface == PHY_INTERFACE_MODE_RGMII_ID ||
+ macb->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID ||
+ macb->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID)
+ val = macb->config->usrio->rgmii;
+ else if (macb->phy_interface == PHY_INTERFACE_MODE_RMII)
+ val = macb->config->usrio->rmii;
+ else if (macb->phy_interface == PHY_INTERFACE_MODE_MII)
+ val = macb->config->usrio->mii;
+
+ if (macb->config->caps & MACB_CAPS_USRIO_HAS_CLKEN)
+ val |= macb->config->usrio->clken;
+
+ gem_writel(macb, USRIO, val);
if (macb->phy_interface == PHY_INTERFACE_MODE_SGMII) {
unsigned int ncfgr = macb_readl(macb, NCFGR);
ncfgr |= GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL);
macb_writel(macb, NCFGR, ncfgr);
}
-#else
-#if defined(CONFIG_RGMII) || defined(CONFIG_RMII)
- gem_writel(macb, USRIO, GEM_BIT(RGMII));
-#else
- gem_writel(macb, USRIO, 0);
-#endif
-#endif
} else {
/* choose RMII or MII mode. This depends on the board */
-#ifdef CONFIG_DM_ETH
#ifdef CONFIG_AT91FAMILY
if (macb->phy_interface == PHY_INTERFACE_MODE_RMII) {
macb_writel(macb, USRIO,
- MACB_BIT(RMII) | MACB_BIT(CLKEN));
+ macb->config->usrio->rmii |
+ macb->config->usrio->clken);
} else {
- macb_writel(macb, USRIO, MACB_BIT(CLKEN));
+ macb_writel(macb, USRIO, macb->config->usrio->clken);
}
#else
if (macb->phy_interface == PHY_INTERFACE_MODE_RMII)
macb_writel(macb, USRIO, 0);
else
- macb_writel(macb, USRIO, MACB_BIT(MII));
-#endif
-#else
-#ifdef CONFIG_RMII
-#ifdef CONFIG_AT91FAMILY
- macb_writel(macb, USRIO, MACB_BIT(RMII) | MACB_BIT(CLKEN));
-#else
- macb_writel(macb, USRIO, 0);
-#endif
-#else
-#ifdef CONFIG_AT91FAMILY
- macb_writel(macb, USRIO, MACB_BIT(CLKEN));
-#else
- macb_writel(macb, USRIO, MACB_BIT(MII));
-#endif
-#endif /* CONFIG_RMII */
+ macb_writel(macb, USRIO, macb->config->usrio->mii);
#endif
}
-#ifdef CONFIG_DM_ETH
ret = macb_phy_init(dev, name);
-#else
- ret = macb_phy_init(macb, name);
-#endif
if (ret)
return ret;
static u32 macb_mdc_clk_div(int id, struct macb_device *macb)
{
u32 config;
-#if defined(CONFIG_DM_ETH) && defined(CONFIG_CLK)
+#if defined(CONFIG_CLK)
unsigned long macb_hz = macb->pclk_rate;
#else
unsigned long macb_hz = get_macb_pclk_rate(id);
{
u32 config;
-#if defined(CONFIG_DM_ETH) && defined(CONFIG_CLK)
+#if defined(CONFIG_CLK)
unsigned long macb_hz = macb->pclk_rate;
#else
unsigned long macb_hz = get_macb_pclk_rate(id);
macb_writel(macb, NCFGR, ncfgr);
}
-#ifndef CONFIG_DM_ETH
-static int macb_send(struct eth_device *netdev, void *packet, int length)
-{
- struct macb_device *macb = to_macb(netdev);
-
- return _macb_send(macb, netdev->name, packet, length);
-}
-
-static int macb_recv(struct eth_device *netdev)
-{
- struct macb_device *macb = to_macb(netdev);
- uchar *packet;
- int length;
-
- macb->wrapped = false;
- for (;;) {
- macb->next_rx_tail = macb->rx_tail;
- length = _macb_recv(macb, &packet);
- if (length >= 0) {
- net_process_received_packet(packet, length);
- reclaim_rx_buffers(macb, macb->next_rx_tail);
- } else {
- return length;
- }
- }
-}
-
-static int macb_init(struct eth_device *netdev, struct bd_info *bd)
-{
- struct macb_device *macb = to_macb(netdev);
-
- return _macb_init(macb, netdev->name);
-}
-
-static void macb_halt(struct eth_device *netdev)
-{
- struct macb_device *macb = to_macb(netdev);
-
- return _macb_halt(macb);
-}
-
-static int macb_write_hwaddr(struct eth_device *netdev)
-{
- struct macb_device *macb = to_macb(netdev);
-
- return _macb_write_hwaddr(macb, netdev->enetaddr);
-}
-
-int macb_eth_initialize(int id, void *regs, unsigned int phy_addr)
-{
- struct macb_device *macb;
- struct eth_device *netdev;
-
- macb = malloc(sizeof(struct macb_device));
- if (!macb) {
- printf("Error: Failed to allocate memory for MACB%d\n", id);
- return -1;
- }
- memset(macb, 0, sizeof(struct macb_device));
-
- netdev = &macb->netdev;
-
- macb->regs = regs;
- macb->phy_addr = phy_addr;
-
- if (macb_is_gem(macb))
- sprintf(netdev->name, "gmac%d", id);
- else
- sprintf(netdev->name, "macb%d", id);
-
- netdev->init = macb_init;
- netdev->halt = macb_halt;
- netdev->send = macb_send;
- netdev->recv = macb_recv;
- netdev->write_hwaddr = macb_write_hwaddr;
-
- _macb_eth_initialize(macb);
-
- eth_register(netdev);
-
-#if defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
- int retval;
- struct mii_dev *mdiodev = mdio_alloc();
- if (!mdiodev)
- return -ENOMEM;
- strncpy(mdiodev->name, netdev->name, MDIO_NAME_LEN);
- mdiodev->read = macb_miiphy_read;
- mdiodev->write = macb_miiphy_write;
-
- retval = mdio_register(mdiodev);
- if (retval < 0)
- return retval;
- macb->bus = miiphy_get_dev_by_name(netdev->name);
-#endif
- return 0;
-}
-#endif /* !CONFIG_DM_ETH */
-
-#ifdef CONFIG_DM_ETH
-
static int macb_start(struct udevice *dev)
{
return _macb_init(dev, dev->name);
}
#endif
-static const struct macb_config default_gem_config = {
+static const struct macb_usrio_cfg macb_default_usrio = {
+ .mii = MACB_BIT(MII),
+ .rmii = MACB_BIT(RMII),
+ .rgmii = GEM_BIT(RGMII),
+ .clken = MACB_BIT(CLKEN),
+};
+
+static struct macb_config default_gem_config = {
.dma_burst_length = 16,
.hw_dma_cap = HW_DMA_CAP_32B,
.clk_init = NULL,
+ .usrio = &macb_default_usrio,
};
static int macb_eth_probe(struct udevice *dev)
struct eth_pdata *pdata = dev_get_plat(dev);
struct macb_device *macb = dev_get_priv(dev);
struct ofnode_phandle_args phandle_args;
- const char *phy_mode;
int ret;
- phy_mode = dev_read_prop(dev, "phy-mode", NULL);
-
- if (phy_mode)
- macb->phy_interface = phy_get_interface_by_name(phy_mode);
- if (macb->phy_interface == -1) {
- debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
+ macb->phy_interface = dev_read_phy_mode(dev);
+ if (macb->phy_interface == PHY_INTERFACE_MODE_NA)
return -EINVAL;
- }
/* Read phyaddr from DT */
if (!dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,
macb->phy_addr = ofnode_read_u32_default(phandle_args.node,
"reg", -1);
- macb->regs = (void *)pdata->iobase;
+ macb->regs = (void *)(uintptr_t)pdata->iobase;
macb->is_big_endian = (cpu_to_be32(0x12345678) == 0x12345678);
macb->config = (struct macb_config *)dev_get_driver_data(dev);
- if (!macb->config)
+ if (!macb->config) {
+ if (IS_ENABLED(CONFIG_DMA_ADDR_T_64BIT)) {
+ if (GEM_BFEXT(DAW64, gem_readl(macb, DCFG6)))
+ default_gem_config.hw_dma_cap = HW_DMA_CAP_64B;
+ }
macb->config = &default_gem_config;
+ }
#ifdef CONFIG_CLK
ret = macb_enable_clk(dev);
macb->bus = mdio_alloc();
if (!macb->bus)
return -ENOMEM;
- strncpy(macb->bus->name, dev->name, MDIO_NAME_LEN);
+ strlcpy(macb->bus->name, dev->name, MDIO_NAME_LEN);
macb->bus->read = macb_miiphy_read;
macb->bus->write = macb_miiphy_write;
static int macb_eth_of_to_plat(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_plat(dev);
+ struct macb_device *macb = dev_get_priv(dev);
+ void *blob = (void *)gd->fdt_blob;
+ int node = dev_of_offset(dev);
+ int fl_node, speed_fdt;
+
+ /* fetch 'fixed-link' property */
+ fl_node = fdt_subnode_offset(blob, node, "fixed-link");
+ if (fl_node >= 0) {
+ /* set phy_addr to invalid value for fixed link */
+ macb->phy_addr = PHY_MAX_ADDR + 1;
+ macb->duplex = fdtdec_get_bool(blob, fl_node, "full-duplex");
+ speed_fdt = fdtdec_get_int(blob, fl_node, "speed", 0);
+ if (speed_fdt == 100) {
+ macb->speed = 1;
+ } else if (speed_fdt == 10) {
+ macb->speed = 0;
+ } else {
+ printf("%s: The given speed %d of ethernet in the DT is not supported\n",
+ __func__, speed_fdt);
+ return -EINVAL;
+ }
+ }
- pdata->iobase = (phys_addr_t)dev_remap_addr(dev);
+ pdata->iobase = (uintptr_t)dev_remap_addr(dev);
if (!pdata->iobase)
return -EINVAL;
return macb_late_eth_of_to_plat(dev);
}
-static const struct macb_config microchip_config = {
- .dma_burst_length = 16,
- .hw_dma_cap = HW_DMA_CAP_64B,
- .clk_init = NULL,
+static const struct macb_usrio_cfg sama7g5_usrio = {
+ .mii = 0,
+ .rmii = 1,
+ .rgmii = 2,
+ .clken = BIT(2),
};
static const struct macb_config sama5d4_config = {
.dma_burst_length = 4,
.hw_dma_cap = HW_DMA_CAP_32B,
.clk_init = NULL,
+ .usrio = &macb_default_usrio,
};
static const struct macb_config sifive_config = {
.dma_burst_length = 16,
.hw_dma_cap = HW_DMA_CAP_32B,
.clk_init = macb_sifive_clk_init,
+ .usrio = &macb_default_usrio,
+};
+
+static const struct macb_config sama7g5_gmac_config = {
+ .dma_burst_length = 16,
+ .hw_dma_cap = HW_DMA_CAP_32B,
+ .clk_init = macb_sama7g5_clk_init,
+ .usrio = &sama7g5_usrio,
+};
+
+static const struct macb_config sama7g5_emac_config = {
+ .caps = MACB_CAPS_USRIO_HAS_CLKEN,
+ .dma_burst_length = 16,
+ .hw_dma_cap = HW_DMA_CAP_32B,
+ .usrio = &sama7g5_usrio,
};
static const struct udevice_id macb_eth_ids[] = {
{ .compatible = "cdns,macb" },
{ .compatible = "cdns,at91sam9260-macb" },
{ .compatible = "cdns,sam9x60-macb" },
+ { .compatible = "cdns,sama7g5-gem",
+ .data = (ulong)&sama7g5_gmac_config },
+ { .compatible = "cdns,sama7g5-emac",
+ .data = (ulong)&sama7g5_emac_config },
{ .compatible = "atmel,sama5d2-gem" },
{ .compatible = "atmel,sama5d3-gem" },
{ .compatible = "atmel,sama5d4-gem", .data = (ulong)&sama5d4_config },
{ .compatible = "cdns,zynq-gem" },
{ .compatible = "sifive,fu540-c000-gem",
.data = (ulong)&sifive_config },
- { .compatible = "microchip,mpfs-mss-gem",
- .data = (ulong)µchip_config },
{ }
};
.plat_auto = sizeof(struct eth_pdata),
};
#endif
-
-#endif